feat: add deterministic goat routine

This commit is contained in:
Rijad Zuzo
2026-07-26 23:52:56 +02:00
parent f79c2bb630
commit e3aa3440a2
61 changed files with 1393 additions and 1057 deletions
+90
View File
@@ -0,0 +1,90 @@
extends Node3D
const HUNGER_CUE_BASE_Y := 2.05
const FED_RESPONSE_BASE_Y := 1.8
@onready var head_root: Node3D = $HeadRoot
@onready var tail_root: Node3D = $TailRoot
@onready var hunger_cue_root: Node3D = $HungerCueRoot
@onready var fed_response_root: Node3D = $FedResponseRoot
@onready var leg_front_left: Node3D = $LegFrontLeft
@onready var leg_front_right: Node3D = $LegFrontRight
@onready var leg_back_left: Node3D = $LegBackLeft
@onready var leg_back_right: Node3D = $LegBackRight
var idle_phase := 0.0
var is_hungry := false
var is_moving := false
var fed_tween: Tween
var head_base_position: Vector3
var visual_base_position: Vector3
func _ready() -> void:
head_base_position = head_root.position
visual_base_position = position
reset_transient_feedback()
func _process(delta: float) -> void:
idle_phase = fmod(idle_phase + delta, TAU)
var breath := sin(idle_phase * 1.7) * 0.025
var hungry_drop := -0.12 if is_hungry else 0.0
var walking_bob := absf(sin(idle_phase * 5.4)) * 0.045 if is_moving else 0.0
position.y = visual_base_position.y + walking_bob
head_root.position.y = head_base_position.y + breath + hungry_drop
head_root.rotation_degrees.x = (
8.0 + sin(idle_phase * 1.2) * 2.0 if is_hungry else -3.0 + sin(idle_phase * 1.4) * 2.5
)
tail_root.rotation_degrees.z = sin(idle_phase * 3.1) * (4.0 if is_hungry else 13.0)
var stride := sin(idle_phase * 5.4) * 14.0 if is_moving else 0.0
leg_front_left.rotation_degrees.x = stride
leg_back_right.rotation_degrees.x = stride
leg_front_right.rotation_degrees.x = -stride
leg_back_left.rotation_degrees.x = -stride
if hunger_cue_root.visible:
hunger_cue_root.position.y = HUNGER_CUE_BASE_Y + sin(idle_phase * 2.2) * 0.07
func set_hungry(value: bool) -> void:
is_hungry = value
hunger_cue_root.visible = value
func set_moving(value: bool) -> void:
is_moving = value
if not value:
position = visual_base_position
leg_front_left.rotation_degrees.x = 0.0
leg_front_right.rotation_degrees.x = 0.0
leg_back_left.rotation_degrees.x = 0.0
leg_back_right.rotation_degrees.x = 0.0
func reset_transient_feedback() -> void:
if fed_tween != null:
fed_tween.kill()
fed_tween = null
fed_response_root.visible = false
fed_response_root.position.y = FED_RESPONSE_BASE_Y
fed_response_root.scale = Vector3(0.2, 0.2, 0.2)
func play_fed_response() -> void:
reset_transient_feedback()
fed_response_root.visible = true
fed_tween = create_tween()
fed_tween.set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
fed_tween.tween_property(fed_response_root, "scale", Vector3.ONE, 0.34)
fed_tween.parallel().tween_property(
fed_response_root, "position:y", FED_RESPONSE_BASE_Y + 0.22, 0.34
)
fed_tween.set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN)
fed_tween.tween_interval(0.7)
fed_tween.tween_property(fed_response_root, "scale", Vector3(0.2, 0.2, 0.2), 0.42)
fed_tween.finished.connect(_on_fed_response_finished)
func _on_fed_response_finished() -> void:
fed_response_root.visible = false
fed_tween = null