From 3080009b37b648edae14e65370151b0f5466222f Mon Sep 17 00:00:00 2001 From: copygirl Date: Thu, 14 Aug 2025 23:34:53 +0200 Subject: [PATCH] Make bumping support multiple skeletons --- copyThrower.gd | 78 +++++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/copyThrower.gd b/copyThrower.gd index 29a9071..608900b 100644 --- a/copyThrower.gd +++ b/copyThrower.gd @@ -14,10 +14,15 @@ extends Mod_Base # Reduces the queue delay as it increases. var combo := 0 -var body_bump := Vector3.ZERO -var head_bump := Quaternion.IDENTITY -var current_body_bump := Vector3.ZERO -var current_head_bump := Quaternion.IDENTITY +# Contains an entry in the format of `DEFAULT_BUMP` for each skeleton that is affected +# by "bumping". This causes the head and body to react to objects colliding with them. +var bump_lookup := {} +var DEFAULT_BUMP := { + body = Vector3.ZERO, + head = Quaternion.IDENTITY, + current_body = Vector3.ZERO, + current_head = Quaternion.IDENTITY, +} var triggers = { # First number is chance to stick. @@ -116,27 +121,35 @@ func _process(delta: float) -> void: ## Applies body and head "bumping" that causes ## the avatar to "shake" in response to being hit. func _apply_bumping(delta: float) -> void: - var skeleton := get_skeleton() - if not skeleton: return - - current_body_bump = current_body_bump.lerp(body_bump, 1 - 0.001 ** delta) - current_head_bump = current_head_bump.slerp(head_bump, 1 - 0.001 ** delta) - body_bump = body_bump.lerp(Vector3.ZERO, 1 - 0.01 ** delta) - head_bump = head_bump.slerp(Quaternion.IDENTITY, 1 - 0.01 ** delta) - - var base_bone := skeleton.find_bone("Hips") - var base_rest := skeleton.get_bone_global_rest(base_bone) - skeleton.set_bone_global_pose(base_bone, base_rest.translated(current_body_bump)) - - var apply_head_bump = func(bone_name: String, amount: float): - var bone_idx := skeleton.find_bone(bone_name) - var bone_rot := skeleton.get_bone_pose_rotation(bone_idx) - var new_rot := Quaternion.IDENTITY.slerp(current_head_bump, amount) * bone_rot - skeleton.set_bone_pose_rotation(bone_idx, new_rot) - - apply_head_bump.call("Head" , 0.6) - apply_head_bump.call("Neck" , 0.3) - apply_head_bump.call("Chest", 0.1) + # Clear our nodes that don't exist anymore. + for skeleton in bump_lookup.keys(): + if not is_instance_valid(skeleton): + bump_lookup.erase(skeleton) + + # Apply bumping to any skeleton that got bumped. + # NOTE: Typically there will only be one skeleton, but for + # example with copyMultiplayer, there could be multiple! + for skeleton: Skeleton3D in bump_lookup: + var bump: Dictionary = bump_lookup[skeleton] + + bump.current_body = bump.current_body.lerp(bump.body, 1 - 0.001 ** delta) + bump.current_head = bump.current_head.slerp(bump.head, 1 - 0.001 ** delta) + bump.body = bump.body.lerp(Vector3.ZERO, 1 - 0.01 ** delta) + bump.head = bump.head.slerp(Quaternion.IDENTITY, 1 - 0.01 ** delta) + + var base_bone := skeleton.find_bone("Hips") + var base_rest := skeleton.get_bone_global_rest(base_bone) + skeleton.set_bone_global_pose(base_bone, base_rest.translated(bump.current_body)) + + var apply_head_bump = func(bone_name: String, amount: float): + var bone_idx := skeleton.find_bone(bone_name) + var bone_rot := skeleton.get_bone_pose_rotation(bone_idx) + var new_rot := Quaternion.IDENTITY.slerp(bump.current_head, amount) * bone_rot + skeleton.set_bone_pose_rotation(bone_idx, new_rot) + + apply_head_bump.call("Head" , 0.6) + apply_head_bump.call("Neck" , 0.3) + apply_head_bump.call("Chest", 0.1) func _throw_hearts_in_queue(delta: float) -> void: if queue.is_empty(): @@ -222,8 +235,15 @@ static func _get_total_curl(skeleton: Skeleton3D, bone: int, current := 0.0) -> func on_collide(object: RigidBody3D, body: CharacterBody3D) -> void: var collider := body.get_parent() as BoneAttachment3D if not collider: return - # Ignore when object collides with a skeleton other than our own. - if collider.get_parent() != get_skeleton(): return + + var skeleton := collider.get_parent() as Skeleton3D + if not skeleton: return + + var bump = bump_lookup.get(skeleton) + if not bump: + # Create a new entry in `bump_lookup` for this skeleton. + bump = DEFAULT_BUMP.duplicate(true) + bump_lookup[skeleton] = bump var pos := object.global_position var vel := object.linear_velocity @@ -233,12 +253,12 @@ func on_collide(object: RigidBody3D, body: CharacterBody3D) -> void: var bone_pos := collider.global_position var rotation := Quaternion(bone_pos.direction_to(pos), bone_pos.direction_to(pos + vel)) rotation = Quaternion.IDENTITY.slerp(rotation, 0.15 * object.size) - head_bump *= rotation + bump.head *= rotation # Hits to any other body part cause the entire body to translate. else: vel.y *= 0.25 # Less vertical influence. - body_bump += vel * object.size * 0.05 + bump.body += vel * object.size * 0.05 static func pride(value: String) -> Texture2D: