47 lines
1.3 KiB
GDScript
47 lines
1.3 KiB
GDScript
extends KinematicBody
|
|
class_name NPC
|
|
|
|
|
|
export(float) var turn_speed = 2.5
|
|
export(float) var speed = 8
|
|
|
|
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)
|
|
|
|
if current_target:
|
|
# Move towards the current goal
|
|
var direction_normalized: Vector3 = (current_target - transform.origin).normalized()
|
|
|
|
look_towards(direction_normalized)
|
|
move_towards(direction_normalized * speed)
|
|
|
|
|
|
func set_position(position: Vector3):
|
|
transform.origin = position
|
|
|
|
|
|
func move_towards(direction_times_speed: Vector3):
|
|
# 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
|