87 lines
2.7 KiB
GDScript
87 lines
2.7 KiB
GDScript
extends Node3D
|
|
|
|
|
|
@onready var skeleton_flying = $BallFlyingMesh.get_node("SKL_projectile_flying/Skeleton3D")
|
|
@onready var skeleton_bouncing = $BallBouncingMesh.get_node("SKL_projectile_bouncing/Skeleton3D")
|
|
@onready var ball = owner
|
|
@onready var timer = ball.get_node("TimerCollision")
|
|
|
|
var is_bouncing = false
|
|
var max_squish_xy = 0.5 # Starts at 0
|
|
var max_squish_z = 0.8 # From 0 to 1
|
|
|
|
|
|
func _ready():
|
|
ball.ball_collision_started.connect(_on_collision)
|
|
ball.ball_collision_ended.connect(_after_collision)
|
|
|
|
|
|
func _process(delta):
|
|
_align_flying_mesh_to_direction()
|
|
_squish_animation()
|
|
|
|
|
|
func _align_flying_mesh_to_direction():
|
|
# Align the DirectionNode to the movement direction
|
|
$DirectionNode.look_at(ball.captured_velocity + ball.global_position, Utilities.LOOK_AT_OFFSET_FIX)
|
|
|
|
# Convert the rotation euler into a quaternion
|
|
var euler_rotation = $DirectionNode.rotation
|
|
var quaternion_rotation : Quaternion
|
|
quaternion_rotation = quaternion_rotation.from_euler(euler_rotation)
|
|
|
|
# Rotate the bone
|
|
skeleton_flying.set_bone_pose_rotation(1, quaternion_rotation)
|
|
|
|
|
|
func _on_collision():
|
|
$BallFlyingMesh.visible = false
|
|
$BallBouncingMesh.visible = true
|
|
is_bouncing = true
|
|
|
|
_align_bouncing_mesh_to_surface()
|
|
|
|
|
|
func _after_collision():
|
|
$BallFlyingMesh.visible = true
|
|
$BallBouncingMesh.visible = false
|
|
is_bouncing = false
|
|
|
|
|
|
func _align_bouncing_mesh_to_surface():
|
|
# Align position to the surface
|
|
var bone_position = ball.collision_position - ball.global_position
|
|
skeleton_bouncing.set_bone_pose_position(1, bone_position)
|
|
|
|
# Align rotation to the surface normal
|
|
$RotationNode.look_at(ball.collision_normal + ball.global_position, Utilities.LOOK_AT_OFFSET_FIX)
|
|
|
|
# Convert the rotation euler into a quaternion
|
|
var euler_rotation = $RotationNode.rotation
|
|
var quaternion_rotation : Quaternion
|
|
quaternion_rotation = quaternion_rotation.from_euler(euler_rotation)
|
|
|
|
# Rotate the bone
|
|
skeleton_bouncing.set_bone_pose_rotation(1, quaternion_rotation)
|
|
|
|
|
|
func _squish_animation():
|
|
if is_bouncing:
|
|
# Remap the time_left value of the timer
|
|
var time_left_remap = remap(timer.time_left, timer.wait_time, 0, 0, 2)
|
|
var time_left_pingpong = pingpong(time_left_remap, 1)
|
|
|
|
# Multiply the scaling by the collision angle factor to reduce
|
|
# the squishing effect at shallow angles
|
|
var scale_xy_factor = 1.0 + (ball.collision_angle_factor * max_squish_xy)
|
|
var scale_xy = 1.0 * remap(time_left_pingpong, 0, 1, 1, scale_xy_factor)
|
|
var scale_z_factor = 1.0 - (ball.collision_angle_factor * max_squish_z)
|
|
var scale_z = 1.0 * remap(time_left_pingpong, 0, 1, 1, scale_z_factor)
|
|
|
|
# Compose the vector for the bone scaling
|
|
var scale_squish_vector = Vector3(scale_xy, scale_xy, scale_z)
|
|
|
|
# Scale the bone
|
|
skeleton_bouncing.set_bone_pose_scale(1, scale_squish_vector)
|
|
|