--- /dev/null
+extends Node3D
+
+
+@onready var _skin := $skin
+var _head_track_arr: Array[Node3D]= []
+
+
+func _pick_head_track_target() -> void:
+ if _head_track_arr.is_empty():
+ _skin.set_head_target(null)
+ _skin.set_eyes_target(null)
+ else:
+ var target: Node3D = _head_track_arr.front()
+ _skin.set_head_target(target)
+ _skin.set_eyes_target(target)
+
+
+func _on_head_turn_area_entered(area: Area3D) -> void:
+ for node in area.get_parent().get_children().filter(func(c): return c.is_in_group("npc-headTrack")):
+ var i = _head_track_arr.find(node)
+ if i < 0:
+ _head_track_arr.append(node)
+ _pick_head_track_target()
+
+
+func _on_head_turn_area_exited(area: Area3D) -> void:
+ for node in area.get_parent().get_children().filter(func(c): return c.is_in_group("npc-headTrack")):
+ var i = _head_track_arr.find(node)
+ if i >= 0:
+ _head_track_arr.remove_at(i)
+ _pick_head_track_target()
--- /dev/null
+[gd_scene load_steps=4 format=3 uid="uid://bmcw5a71lsldu"]
+
+[ext_resource type="PackedScene" uid="uid://2tvylmtejq0u" path="res://william.tscn" id="1_fk6op"]
+[ext_resource type="Script" path="res://test/npc.gd" id="1_tko4h"]
+
+[sub_resource type="CylinderShape3D" id="CylinderShape3D_rgxya"]
+radius = 3.27162
+
+[node name="NonPlayerCharacter" type="Node3D"]
+script = ExtResource("1_tko4h")
+
+[node name="skin" parent="." instance=ExtResource("1_fk6op")]
+
+[node name="headTurn" type="Area3D" parent="skin"]
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="skin/headTurn"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 3.17898)
+shape = SubResource("CylinderShape3D_rgxya")
+
+[node name="playerTrackPoint" type="Node3D" parent="skin" groups=["player-eyeTrack", "player-headTrack"]]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.77777, 0.0828433)
+
+[connection signal="area_entered" from="skin/headTurn" to="." method="_on_head_turn_area_entered"]
+[connection signal="area_exited" from="skin/headTurn" to="." method="_on_head_turn_area_exited"]