fix(vagrant): iteration — body+head look-at, WASD-driven leg-facing, idle-collapse
- humanoid.rig.json: root removed from upper track; body look_at + slow speed (180 deg/s, lazy); head fast speed (480 deg/s) + +-90 deg limits; puppet dep bumped to 0.3.1 - animations/idle_lower.anim.json (NEW): leg+foot scl=[mirror, 0] keeps legs invisible at idle (locomotion skips animated bones; foot cascade zeros out) - init.lua: set_procedural 'facing' callback writes root.rot from last_walk_rot_deg each frame; WASD-vector updates last_walk_rot_deg via atan(dx, -dy); idle_lower played parallel to idle, stopped during walk Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
22
init.lua
22
init.lua
@@ -1,4 +1,4 @@
|
||||
-- sporel-module-vagrant-skeleton v0.2.0
|
||||
-- sporel-module-vagrant-skeleton v0.3.1
|
||||
-- Sprite-mode test-chamber: 13-bone humanoid puppet + sprite-tilemap +
|
||||
-- hardcoded furniture. F.vagrant Tier-1 + Sprite-Upgrade-Bridge state.
|
||||
|
||||
@@ -17,6 +17,7 @@ local state = {
|
||||
bed_tex = nil,
|
||||
bench_tex = nil,
|
||||
backpack_tex = nil,
|
||||
last_walk_rot_deg = 0, -- persisted root.rot (degrees) across idle frames
|
||||
}
|
||||
|
||||
-- CI hook gating (mirrors Phase 1 convention).
|
||||
@@ -34,6 +35,7 @@ local function set_walk_or_idle(moving)
|
||||
if moving then
|
||||
if not puppet.is_playing(state.player, "walk") then
|
||||
puppet.stop(state.player, "idle")
|
||||
puppet.stop(state.player, "idle_lower")
|
||||
puppet.play(state.player, "walk", { loop = true })
|
||||
puppet.play(state.player, "walk_upper", { loop = true })
|
||||
end
|
||||
@@ -41,7 +43,8 @@ local function set_walk_or_idle(moving)
|
||||
if not puppet.is_playing(state.player, "idle") then
|
||||
puppet.stop(state.player, "walk")
|
||||
puppet.stop(state.player, "walk_upper")
|
||||
puppet.play(state.player, "idle", { loop = true })
|
||||
puppet.play(state.player, "idle", { loop = true })
|
||||
puppet.play(state.player, "idle_lower", { loop = true })
|
||||
end
|
||||
end
|
||||
if CI_FRAME_PERF and new_state ~= ci_last_state then
|
||||
@@ -64,10 +67,20 @@ function M.init(ctx)
|
||||
local walk = puppet.load_animation("animations/walk.anim.json", rig)
|
||||
local walk_upper = puppet.load_animation("animations/walk_upper.anim.json", rig)
|
||||
local idle = puppet.load_animation("animations/idle.anim.json", rig)
|
||||
local idle_lower = puppet.load_animation("animations/idle_lower.anim.json", rig)
|
||||
puppet.register_animation(state.player, idle)
|
||||
puppet.register_animation(state.player, walk)
|
||||
puppet.register_animation(state.player, walk_upper)
|
||||
puppet.play(state.player, "idle", { loop = true })
|
||||
puppet.register_animation(state.player, idle_lower)
|
||||
puppet.play(state.player, "idle", { loop = true })
|
||||
puppet.play(state.player, "idle_lower", { loop = true })
|
||||
|
||||
-- Procedural facing: root.rot = state.last_walk_rot_deg every frame.
|
||||
-- Fires inside update_bone_recursive at root-visit (after reset, before compute_world).
|
||||
-- Root is not in any track, so write_bone bypasses track-guard.
|
||||
puppet.set_procedural(state.player, "facing", function(handle, dt)
|
||||
puppet.write_bone(handle, "root", { rot = state.last_walk_rot_deg })
|
||||
end)
|
||||
|
||||
-- Furniture textures (preload to avoid first-frame load stutter).
|
||||
local world_lib = aliases.world
|
||||
@@ -113,6 +126,7 @@ function M.update(ctx, dt)
|
||||
if ci_drive_frame > 20 and ci_drive_frame <= 40 then
|
||||
dx = 1; dy = 0
|
||||
moving = true
|
||||
state.last_walk_rot_deg = math.deg(math.atan(dx, -dy)) -- atan(1, 0) = pi/2 = 90deg
|
||||
local pos = puppet.position(state.player)
|
||||
puppet.move_to(state.player,
|
||||
pos.x + dx * state.player_speed * dt, pos.y)
|
||||
@@ -123,6 +137,8 @@ function M.update(ctx, dt)
|
||||
|
||||
if moving and not CI_DRIVE then
|
||||
local len = math.sqrt(dx * dx + dy * dy)
|
||||
-- Update last_walk_rot_deg (sprite-top convention: angle=atan(dx,-dy)).
|
||||
state.last_walk_rot_deg = math.deg(math.atan(dx / len, -dy / len))
|
||||
local pos = puppet.position(state.player)
|
||||
puppet.move_to(state.player,
|
||||
pos.x + dx / len * state.player_speed * dt,
|
||||
|
||||
Reference in New Issue
Block a user