feat(characters): add modular woodland traveler kit
This commit is contained in:
+45
-17
@@ -9,6 +9,7 @@ const TRUST_REACTION_START_SCALE := Vector3(0.24, 0.24, 0.24)
|
||||
const CONCERN_BASE_POSITION := Vector3(-0.4, 3.25, 0.0)
|
||||
|
||||
@export var debug_logs := false
|
||||
@export var appearance: CharacterAppearanceProfile
|
||||
|
||||
@export var move_speed := 3.0
|
||||
@export var rotation_speed := 8.0
|
||||
@@ -58,6 +59,9 @@ var walk_phase := 0.0
|
||||
var glyph_phase := 0.0
|
||||
var concern_phase := 0.0
|
||||
var trust_reaction_tween: Tween
|
||||
var rest_heights := Vector3(1.05, 1.68, 1.9)
|
||||
var arm_swing := 1.0
|
||||
var cue_lift := 0.0
|
||||
|
||||
|
||||
func debug_log(message: String) -> void:
|
||||
@@ -76,11 +80,13 @@ func _process(delta: float) -> void:
|
||||
return
|
||||
glyph_phase = fmod(glyph_phase + delta * 2.2, TAU)
|
||||
if task_glyph_root.visible:
|
||||
task_glyph_root.position.y = 2.9 + sin(glyph_phase) * 0.045
|
||||
task_glyph_root.position.y = 2.9 + cue_lift + sin(glyph_phase) * 0.045
|
||||
task_glyph_root.rotation.y = glyph_phase * 0.35
|
||||
if opportunity_concern_root.visible:
|
||||
concern_phase = fmod(concern_phase + delta * 1.65, TAU)
|
||||
opportunity_concern_root.position.y = (CONCERN_BASE_POSITION.y + sin(concern_phase) * 0.045)
|
||||
opportunity_concern_root.position.y = (
|
||||
CONCERN_BASE_POSITION.y + cue_lift + sin(concern_phase) * 0.045
|
||||
)
|
||||
opportunity_concern_root.rotation.y = sin(concern_phase * 0.7) * 0.16
|
||||
var concern_scale := 0.96 + sin(concern_phase) * 0.04
|
||||
opportunity_concern_root.scale = Vector3.ONE * concern_scale
|
||||
@@ -92,20 +98,24 @@ func _process(delta: float) -> void:
|
||||
var swing := sin(walk_phase)
|
||||
left_leg.rotation_degrees.x = lerpf(left_leg.rotation_degrees.x, swing * 28.0, blend)
|
||||
right_leg.rotation_degrees.x = lerpf(right_leg.rotation_degrees.x, -swing * 28.0, blend)
|
||||
left_arm.rotation_degrees.x = lerpf(left_arm.rotation_degrees.x, -swing * 20.0, blend)
|
||||
right_arm.rotation_degrees.x = lerpf(right_arm.rotation_degrees.x, swing * 20.0, blend)
|
||||
left_arm.rotation_degrees.x = lerpf(
|
||||
left_arm.rotation_degrees.x, -swing * 20.0 * arm_swing, blend
|
||||
)
|
||||
right_arm.rotation_degrees.x = lerpf(
|
||||
right_arm.rotation_degrees.x, swing * 20.0 * arm_swing, blend
|
||||
)
|
||||
var step_bob := absf(sin(walk_phase * 2.0)) * 0.035
|
||||
body_mesh.position.y = lerpf(body_mesh.position.y, 1.05 + step_bob, blend)
|
||||
head_mesh.position.y = lerpf(head_mesh.position.y, 1.68 + step_bob, blend)
|
||||
hair_mesh.position.y = lerpf(hair_mesh.position.y, 1.9 + step_bob, blend)
|
||||
body_mesh.position.y = lerpf(body_mesh.position.y, rest_heights.x + step_bob, blend)
|
||||
head_mesh.position.y = lerpf(head_mesh.position.y, rest_heights.y + step_bob, blend)
|
||||
hair_mesh.position.y = lerpf(hair_mesh.position.y, rest_heights.z + step_bob, blend)
|
||||
else:
|
||||
left_leg.rotation_degrees.x = lerpf(left_leg.rotation_degrees.x, 0.0, blend)
|
||||
right_leg.rotation_degrees.x = lerpf(right_leg.rotation_degrees.x, 0.0, blend)
|
||||
left_arm.rotation_degrees.x = lerpf(left_arm.rotation_degrees.x, 0.0, blend)
|
||||
right_arm.rotation_degrees.x = lerpf(right_arm.rotation_degrees.x, 0.0, blend)
|
||||
body_mesh.position.y = lerpf(body_mesh.position.y, 1.05, blend)
|
||||
head_mesh.position.y = lerpf(head_mesh.position.y, 1.68, blend)
|
||||
hair_mesh.position.y = lerpf(hair_mesh.position.y, 1.9, blend)
|
||||
body_mesh.position.y = lerpf(body_mesh.position.y, rest_heights.x, blend)
|
||||
head_mesh.position.y = lerpf(head_mesh.position.y, rest_heights.y, blend)
|
||||
hair_mesh.position.y = lerpf(hair_mesh.position.y, rest_heights.z, blend)
|
||||
|
||||
|
||||
func setup_from_sim(npc: SimNPC) -> void:
|
||||
@@ -123,7 +133,12 @@ func setup_from_sim(npc: SimNPC) -> void:
|
||||
|
||||
|
||||
func _apply_personal_details() -> void:
|
||||
AnimalAppearance.apply_to(self, sim_id, true)
|
||||
AnimalAppearance.apply_to(self, sim_id, true, appearance)
|
||||
rest_heights = AnimalAppearance.rest_heights(self, true)
|
||||
arm_swing = get_meta("arm_swing", 1.0)
|
||||
cue_lift = maxf(0.0, float(get_meta("character_top", 2.6)) - 2.6)
|
||||
task_glyph_root.position.y = 2.9 + cue_lift
|
||||
profession_label.position.y = 2.8 + cue_lift
|
||||
|
||||
|
||||
func _apply_profession_presentation() -> void:
|
||||
@@ -140,11 +155,24 @@ func _apply_profession_presentation() -> void:
|
||||
prop_material.roughness = 0.78
|
||||
profession_prop.material_override = prop_material
|
||||
profession_prop.mesh = _create_profession_prop_mesh()
|
||||
_fit_carried_props()
|
||||
profession_prop.visible = profession_prop.mesh != null
|
||||
profession_label.text = "%s\n%s" % [npc_name, definition.display_name]
|
||||
profession_label.visible = debug_overlay_visible
|
||||
|
||||
|
||||
func _fit_carried_props() -> void:
|
||||
var profile := get_meta("character_appearance") as CharacterAppearanceProfile
|
||||
var lift := Vector3.UP * 0.61 * (profile.leg_length - 1.0) * profile.height
|
||||
var reach := 0.60 + 0.10 * profile.body_fullness
|
||||
profession_prop.position.x = signf(profession_prop.position.x) * reach
|
||||
profession_prop.position.z = 0.20
|
||||
profession_prop.position = profession_prop.position * profile.height + lift
|
||||
profession_prop.scale = Vector3.ONE * profile.height
|
||||
carried_food_visual.position = Vector3(reach, 0.70, 0.32) * profile.height + lift
|
||||
carried_wood_visual.position = Vector3(-reach, 0.88, 0.18) * profile.height + lift
|
||||
|
||||
|
||||
func _create_profession_prop_mesh() -> PrimitiveMesh:
|
||||
profession_prop.position = Vector3(0.48, 0.85, 0.0)
|
||||
profession_prop.rotation_degrees = Vector3.ZERO
|
||||
@@ -204,7 +232,7 @@ func set_opportunity_concern_visible(is_visible: bool) -> void:
|
||||
if opportunity_concern_root == null:
|
||||
return
|
||||
opportunity_concern_root.visible = is_visible and not is_dead_visual
|
||||
opportunity_concern_root.position = CONCERN_BASE_POSITION
|
||||
opportunity_concern_root.position = CONCERN_BASE_POSITION + Vector3.UP * cue_lift
|
||||
opportunity_concern_root.rotation = Vector3.ZERO
|
||||
opportunity_concern_root.scale = Vector3.ONE
|
||||
if is_visible:
|
||||
@@ -222,7 +250,7 @@ func play_trust_gain_reaction() -> void:
|
||||
return
|
||||
_stop_trust_gain_reaction()
|
||||
trust_reaction_root.visible = true
|
||||
trust_reaction_root.position = TRUST_REACTION_BASE_POSITION
|
||||
trust_reaction_root.position = TRUST_REACTION_BASE_POSITION + Vector3.UP * cue_lift
|
||||
trust_reaction_root.rotation = Vector3.ZERO
|
||||
trust_reaction_root.scale = TRUST_REACTION_START_SCALE
|
||||
_set_trust_reaction_transparency(1.0)
|
||||
@@ -234,14 +262,14 @@ func play_trust_gain_reaction() -> void:
|
||||
trust_reaction_tween.tween_property(
|
||||
trust_reaction_root,
|
||||
"position",
|
||||
TRUST_REACTION_BASE_POSITION + Vector3(0.0, 0.16, 0.0),
|
||||
TRUST_REACTION_BASE_POSITION + Vector3(0.0, 0.16 + cue_lift, 0.0),
|
||||
0.68
|
||||
)
|
||||
trust_reaction_tween.parallel().tween_property(trust_reaction_root, "rotation:y", 0.32, 0.68)
|
||||
trust_reaction_tween.tween_property(
|
||||
trust_reaction_root,
|
||||
"position",
|
||||
TRUST_REACTION_BASE_POSITION + Vector3(0.0, 0.44, 0.0),
|
||||
TRUST_REACTION_BASE_POSITION + Vector3(0.0, 0.44 + cue_lift, 0.0),
|
||||
0.55
|
||||
)
|
||||
trust_reaction_tween.parallel().tween_property(
|
||||
@@ -258,7 +286,7 @@ func _set_trust_reaction_transparency(value: float) -> void:
|
||||
|
||||
func _finish_trust_gain_reaction() -> void:
|
||||
trust_reaction_root.visible = false
|
||||
trust_reaction_root.position = TRUST_REACTION_BASE_POSITION
|
||||
trust_reaction_root.position = TRUST_REACTION_BASE_POSITION + Vector3.UP * cue_lift
|
||||
trust_reaction_root.rotation = Vector3.ZERO
|
||||
trust_reaction_root.scale = TRUST_REACTION_START_SCALE
|
||||
_set_trust_reaction_transparency(1.0)
|
||||
@@ -272,7 +300,7 @@ func _stop_trust_gain_reaction() -> void:
|
||||
if trust_reaction_root == null:
|
||||
return
|
||||
trust_reaction_root.visible = false
|
||||
trust_reaction_root.position = TRUST_REACTION_BASE_POSITION
|
||||
trust_reaction_root.position = TRUST_REACTION_BASE_POSITION + Vector3.UP * cue_lift
|
||||
trust_reaction_root.rotation = Vector3.ZERO
|
||||
trust_reaction_root.scale = TRUST_REACTION_START_SCALE
|
||||
_set_trust_reaction_transparency(1.0)
|
||||
|
||||
Reference in New Issue
Block a user