From 603e21b6fee9e04b512473832b5937db6f7c2998 Mon Sep 17 00:00:00 2001 From: karl Date: Mon, 11 Nov 2019 11:18:06 +0100 Subject: [PATCH] Smooth NPC turning The Meldewesen now turns smoothly instead of abruptly. In addition, while turning, its move speed decreases, causing it to mostly turn on the spot. --- Characters/NPC.gd | 29 ++++++++++++++++++++++++-- Characters/Util/PathNavigatorForNPC.gd | 5 +---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Characters/NPC.gd b/Characters/NPC.gd index ed3b568..5af2668 100644 --- a/Characters/NPC.gd +++ b/Characters/NPC.gd @@ -2,7 +2,24 @@ extends KinematicBody class_name NPC -var current_target = null +export(float) var turn_speed = 2.5 + +var current_target +var current_look_target + + +func _process(delta): + if current_look_target: + var diff_raw = (current_look_target - -transform.basis.z) + + # Don't look up/down, only rotate on XZ plane + var diff = Vector3(diff_raw.x, 0.0, diff_raw.z) + + # For the target, move the current forward direction towards the desired one + var target = -transform.basis.z + diff * turn_speed * delta + + if diff.length() > 0.1: + look_at(transform.origin + target, Vector3.UP) func set_position(position: Vector3): @@ -10,4 +27,12 @@ func set_position(position: Vector3): func move_towards(direction_times_speed: Vector3): - move_and_slide(direction_times_speed) \ No newline at end of file + # Decrease the speed depending on the difference between the look direction and the move direction + # This makes the NPC stop when turning, and only start moving once it has moved its gaze there + var speed_dir_factor = 1.0 - (-transform.basis.z.normalized() - direction_times_speed.normalized()).length() / 2.0 + + move_and_slide(direction_times_speed * speed_dir_factor) + + +func look_towards(direction: Vector3): + current_look_target = direction diff --git a/Characters/Util/PathNavigatorForNPC.gd b/Characters/Util/PathNavigatorForNPC.gd index 4a4fa94..7f4c603 100644 --- a/Characters/Util/PathNavigatorForNPC.gd +++ b/Characters/Util/PathNavigatorForNPC.gd @@ -51,10 +51,7 @@ func _process(delta): body.move_towards(direction_normalized * speed) # Look towards that goal as well - # Avoid look_at if we're already (almost) there, since that'd be an invalid look direction - # that can be identical to the up vector (which causes problems) - if direction.length() > 0.5: - body.look_at(_get_body_position() + direction_normalized, Vector3.UP) + body.look_towards(direction_normalized) # Returns the point we should currently be moving towards