Allow grabbing (and throwing) hearts

main
copygirl 2 days ago
parent 4cd2c4641a
commit 6450218fcc
  1. 19
      Resources/heart.gd
  2. 1
      Resources/heart.tscn
  3. 61
      copyThrower.gd

@ -86,8 +86,8 @@ func _process(delta: float) -> void:
if get_parent() is CharacterBody3D:
sticky_timer -= delta
if sticky_timer <= 0:
set_physics_active(true)
reparent(original_parent)
freeze = false
func on_body_entered(body: Node) -> void:
if not (body is CharacterBody3D): return
@ -99,20 +99,5 @@ func on_body_entered(body: Node) -> void:
if sticky:
await get_tree().process_frame;
set_physics_active(false)
set_gravity_scale(0.0)
reparent(body)
func set_physics_active(active: bool) -> void:
if active:
sleeping = false
collision_mask = 1
set_gravity_scale(1.0)
else:
sleeping = true
linear_velocity = Vector3.ZERO
angular_velocity = Vector3.ZERO
collision_mask = 0
collision_layer = 0
set_gravity_scale(0.0)
freeze = true

@ -10,6 +10,7 @@ height = 0.04
radius = 0.055
[node name="Heart" type="RigidBody3D"]
collision_layer = 0
contact_monitor = true
max_contacts_reported = 1
script = ExtResource("1_h4gh1")

@ -48,9 +48,30 @@ var triggers = {
"TransgenderPride" : [ 0.35, pride("transgender") ],
}
const HAND_CLOSE_THRESHOLD : float = 12.0
const HAND_OPEN_TRHESHOLD : float = 8.0
var hands := {
RightHand = { closed = false, collider = null },
LeftHand = { closed = false, collider = null },
}
var queue: Array[RigidBody3D] = []
var queue_delay := 0.0
func scene_init() -> void:
# Reset collider values, in case hands aren't found.
for hand in hands.values(): hand.collider = null
var skeleton := get_skeleton()
if not skeleton: return
for child in skeleton.get_children():
var collider := child as AvatarCollider
if not collider: continue
var hand = hands.get(collider.bone_name)
if not hand: continue
hand.collider = collider
func handle_channel_chat_message(
_cheerer_username: String,
_cheerer_display_name: String,
@ -90,6 +111,7 @@ func handle_channel_chat_message(
func _process(delta: float) -> void:
_apply_bumping(delta)
_throw_hearts_in_queue(delta)
_grab_with_hands()
## Applies body and head "bumping" that causes
## the avatar to "shake" in response to being hit.
@ -156,6 +178,45 @@ func _throw_hearts_in_queue(delta: float) -> void:
object.global_position = pos
object.linear_velocity = vel
object.add_to_group("copyThrower/objects")
func _grab_with_hands() -> void:
for hand in hands.values():
if not hand.collider: continue
var closedness = _hand_closedness(hand.collider)
# When hand has just been closed, grab nearby hearts and reparent.
if (not hand.closed) and (closedness > HAND_CLOSE_THRESHOLD):
var body: CharacterBody3D = hand.collider.get_node("CharacterBody3D")
var hand_center = body.to_global(Vector3(0, 0, 0.08))
for object: RigidBody3D in get_tree().get_nodes_in_group("copyThrower/objects"):
if object.global_position.distance_to(hand_center) < 0.16:
object.reparent(hand.collider)
object.global_position = hand_center
object.freeze = true
hand.closed = true
# When hand has just been opened, throw any grabbed hearts.
elif hand.closed and (closedness < HAND_OPEN_TRHESHOLD):
for hand_child in hand.collider.get_children():
var object := hand_child as RigidBody3D
if not object: continue
object.reparent(object.original_parent)
object.linear_velocity = Vector3(0, 1.5, 3.0) * hand.collider.global_basis + Vector3.UP
object.freeze = false
hand.closed = false
static func _hand_closedness(collider: AvatarCollider) -> float:
var total := 0.0
var skeleton := collider.get_skeleton()
var fingers := skeleton.get_bone_children(collider.bone_idx)
for finger in fingers: total += _get_total_curl(skeleton, finger)
return total
static func _get_total_curl(skeleton: Skeleton3D, bone: int, current := 0.0) -> float:
current += skeleton.get_bone_pose_rotation(bone).get_euler().x
var children := skeleton.get_bone_children(bone)
if children.size() == 1:
return _get_total_curl(skeleton, children[0], current)
else: return current
func on_collide(object: RigidBody3D, body: CharacterBody3D) -> void:

Loading…
Cancel
Save