feat(camera): third-person rig, V toggle, visible body
One pawn, both rigs (ADR-9): a skeletal body hidden in first person, a collision-tested spring arm, and a toggle that swaps the active camera and the body's visibility. Shipped default stays first person; -thirdperson starts the pawn in the third-person rig so the review shot is reproducible, and the screenshot run passes it. Three defects found and two fixed: - The skin material had no SkeletalMesh usage flag, so Unreal silently substituted the default grey. That is why the body rendered as clay. - render_screenshots.sh still called ./Engine/... on this branch (the fix lives on the facade branch and never reached main); applied here so the shots generate. - OPEN: the idle clip is bound and PlayAnimation is called - the run logs the clip name - but the body still renders in bind pose, arms out. Recorded with that evidence in TODO.md rather than called done. Shot 5 (demo-third-person) added and documented; camera collision is implemented but unproven, since the spawn has open space behind it.
This commit is contained in:
1 parent
96238bdb6a
commit
05c1488c00
49 files changed
+333
-65
No files matched your search
@@ -55,6 +55,20 @@ ELBOW = 0.18
|
||||
|
||||
PARTS: list[dict] = []
|
||||
|
||||
# The .blend stores the raw A-pose bind: `mpfb_character_export.py --pose idle`
|
||||
# bakes the arms down only in the exported FBX, not in the file. A clip that
|
||||
# animates only swing therefore leaves the arms out in an A — which is exactly how
|
||||
# the first third-person render looked. These are the same deltas `IDLE_POSE` uses,
|
||||
# applied as a base that every key sits on top of.
|
||||
BASE = {
|
||||
"shoulder01.L": (0.0, -0.15, -0.03),
|
||||
"shoulder01.R": (0.0, 0.15, 0.03),
|
||||
"upperarm01.L": (0.0, 0.0, -1.55),
|
||||
"upperarm01.R": (0.0, 0.0, 1.55),
|
||||
"lowerarm01.L": (0.0, 0.0, -0.10),
|
||||
"lowerarm01.R": (0.0, 0.0, 0.10),
|
||||
}
|
||||
|
||||
|
||||
def log(msg):
|
||||
PARTS.append(msg)
|
||||
@@ -78,7 +92,9 @@ def pose_bones(arm):
|
||||
|
||||
|
||||
def key_euler(pb, frame, x=0.0, y=0.0, z=0.0):
|
||||
pb.rotation_euler = (x, y, z)
|
||||
"""Key a pose-bone rotation on top of the arms-down base."""
|
||||
bx, by, bz = BASE.get(pb.name, (0.0, 0.0, 0.0))
|
||||
pb.rotation_euler = (bx + x, by + y, bz + z)
|
||||
pb.keyframe_insert(data_path="rotation_euler", frame=frame)
|
||||
|
||||
|
||||
|
||||
@@ -39,8 +39,11 @@ run_cmdlet ue_build_review_map.py "5/6 stage the demo shot cameras"
|
||||
tail -3 /tmp/ue-review-map-result.txt 2>/dev/null || true
|
||||
|
||||
echo "== 6/6 capture the demo map =="
|
||||
./Engine/Binaries/Linux/UnrealEditor-Cmd "$PROJ" /Game/Hollywood/DemoMap \
|
||||
-game -windowed -ResX=1920 -ResY=1080 -nopause -nosplash -stdout
|
||||
# Absolute engine path: this step runs from the repo, not from $ENGINE, and a bare
|
||||
# ./Engine/... failed with "No such file or directory" while every commandlet above
|
||||
# succeeded through run_cmdlet's cd. -thirdperson so the review shows the body.
|
||||
"$ENGINE/Engine/Binaries/Linux/UnrealEditor-Cmd" "$PROJ" /Game/Hollywood/DemoMap \
|
||||
-game -windowed -ResX=1920 -ResY=1080 -nopause -nosplash -thirdperson -stdout
|
||||
|
||||
echo "== collect the demo screenshots =="
|
||||
mkdir -p "$REPO/Screenshots/demo"
|
||||
|
||||
@@ -308,6 +308,11 @@ try:
|
||||
# (X -22750) and look NORTH toward the mass. The old camera was at
|
||||
# X -22800 Y +2600 aiming at its own X, giving an 85%-sky frame.
|
||||
("demo-north-buildings", unreal.Vector(-22750, 1600, 500), unreal.Vector(-22750, -5200, 350)),
|
||||
# 0.2.0 third-person body. Stands where the pawn's own boom camera sits —
|
||||
# 3.4 m behind the spawn point, 1 m above it — and looks at the pawn, so
|
||||
# the visible body and its idle clip are what the shot is for.
|
||||
# Demo_PlayerStart is at (-13336, -1150, 600), yaw 90 (facing +Y).
|
||||
("demo-third-person", unreal.Vector(-13336, -1750, 780), unreal.Vector(-13336, -1150, 560), 58.0),
|
||||
]
|
||||
seq = spawn(unreal.GigLineShotActor, unreal.Vector(0, 0, 300), "ShotSequencer")
|
||||
if seq:
|
||||
|
||||
@@ -127,6 +127,10 @@ def build():
|
||||
ia_reset.set_editor_property("value_type", unreal.InputActionValueType.BOOLEAN)
|
||||
save(ia_reset)
|
||||
|
||||
ia_cam = fresh("IA_ToggleCamera", unreal.InputAction, unreal.InputAction_Factory)
|
||||
ia_cam.set_editor_property("value_type", unreal.InputActionValueType.BOOLEAN)
|
||||
save(ia_cam)
|
||||
|
||||
ia_pause = fresh("IA_Pause", unreal.InputAction, unreal.InputAction_Factory)
|
||||
ia_pause.set_editor_property("value_type", unreal.InputActionValueType.BOOLEAN)
|
||||
save(ia_pause)
|
||||
@@ -136,7 +140,7 @@ def build():
|
||||
(ia_move, "Gamepad_LeftY"), (ia_strafe, "Gamepad_LeftX"),
|
||||
(ia_look, "MouseX"), (ia_look, "MouseY"), (ia_look, "Gamepad_Right2D"),
|
||||
(ia_jump, "SpaceBar"), (ia_jump, "Gamepad_FaceButton_Bottom"),
|
||||
(ia_reset, "R"), (ia_pause, "Escape"),
|
||||
(ia_reset, "R"), (ia_pause, "Escape"), (ia_cam, "V"),
|
||||
]
|
||||
|
||||
mappings = []
|
||||
|
||||
@@ -48,6 +48,18 @@
|
||||
"Art/reference/north-chinese/01-grauman-s-chinese-theatre-by-carol-highsmith.jpg"
|
||||
],
|
||||
"expect": "The two north-side buildings (TCL Chinese Theatre, Madame Tussaud's) seen from across Hollywood Boulevard, full height in frame, daylight"
|
||||
},
|
||||
{
|
||||
"name": "demo-third-person",
|
||||
"shot": "Screenshots/demo/review-demo-third-person.png",
|
||||
"size": [
|
||||
1920,
|
||||
1080
|
||||
],
|
||||
"references": [
|
||||
"Art/reference/hollywood/el-capitan-facade-day-wikimedia-2009-10-27.jpg"
|
||||
],
|
||||
"expect": "Third-person view of the player body standing on the north sidewalk, full figure visible from behind, the hero facade across the street, daylight"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user