class_name NonPlayerCharacter extends CharacterBody3D @export var reacts_to_player:bool = true : set (value): reacts_to_player = _set_reacts_to_player(value) get: return reacts_to_player @onready var geometry: Node3D = null @onready var player_detection: Area3D = %PlayerDetection @onready var default_geometry: Node3D = %DefaultGeometry @onready var animation_player: AnimationPlayer = %AnimationPlayer const SPEED = 5.0 const JUMP_VELOCITY = 4.5 var tracking_node:Node3D = null var look_direction:Vector3 = Vector3.BACK var look_direction_damper:SpringDamper = SpringDamper.new(Vector3.ZERO, 2, 0.003, 0.003) func _set_reacts_to_player(value:bool) -> bool: if player_detection != null: player_detection.monitoring = value return value func _ready() -> void: player_detection.monitoring = reacts_to_player geometry = find_child("Geometry") if geometry == null: geometry = default_geometry else: default_geometry.visible = false animation_player.set_root("Geometry") func _physics_process(delta: float) -> void: var damped_look_direction = look_direction_damper.calc_clamped_speed(geometry.global_basis.z, look_direction, delta, 3.141) if tracking_node != null: look_direction = (tracking_node.global_position - global_position).normalized() look_direction.y = position.y geometry.look_at(position - damped_look_direction, Vector3.UP) func _on_player_detection_body_entered(body: Node3D) -> void: tracking_node = body func _on_player_detection_body_exited(body: Node3D) -> void: look_direction = Vector3.BACK if body == tracking_node: tracking_node = null