review: split the rounds into named shots and stage the player pawn
Roadmap gains two sections: 'Review scene and player placement' (this pass) and 'Character development' (follow-on). The camera list is now one table of (name, location, target) with look-at rotations computed from the pairs, so a camera cannot drift out of aim when one number changes. New shots: player-placement (the real pawn, staged in the build script), ground-contact (knee height, feet on the plane), shadow-compare (floating vs grounded cube from a low angle), and hero-portals (whole elevation). The review floor grows to 160 m so the facade stands on ground rather than the horizon band. Retired: the first-person shot. Honest gap recorded in the roadmap: the hero portals sit behind the colonnade and do not resolve from the review floor; that needs a camera on the plinth or a portal rebuild, not another angle.
This commit is contained in:
1 parent
0383eabc8e
commit
e46a877556
15 files changed
+174
-147
No files matched your search
@@ -19,8 +19,9 @@ cd "$ENGINE"
|
||||
cat /tmp/ue-review-map-result.txt
|
||||
|
||||
echo "== 2/3 run game on review map =="
|
||||
# -windowed -NoSplash: a fullscreen swap can leave the first frame uncaptured.
|
||||
./Engine/Binaries/Linux/UnrealEditor-Cmd "$PROJ" /Game/Test/ReviewMap \
|
||||
-game -ResX=1920 -ResY=1080 -nopause -nosplash -stdout
|
||||
-game -windowed -ResX=1920 -ResY=1080 -nopause -nosplash -stdout
|
||||
|
||||
echo "== 3/3 collect screenshots =="
|
||||
mkdir -p "$REPO/Screenshots"
|
||||
|
||||
@@ -61,12 +61,14 @@ try:
|
||||
if floor_mesh and floor_mat:
|
||||
# 1 m reference cube scaled to 90 m x 90 m x 0.1 m, top face at Z 0. The
|
||||
# scale is applied on the actor, so Z is -5 cm (+/- 5 cm around centre).
|
||||
floor = spawn(unreal.StaticMeshActor, unreal.Vector(0, 450, -5.0), "ReviewFloor",
|
||||
scale=(90.0, 90.0, 0.1))
|
||||
# Covers the review scene AND the hero blockout 100 m away, so facade shots
|
||||
# no longer end at the black horizon band (160 m square, top face at Z 0).
|
||||
floor = spawn(unreal.StaticMeshActor, unreal.Vector(-5000, 450, -5.0), "ReviewFloor",
|
||||
scale=(160.0, 160.0, 0.1))
|
||||
if floor:
|
||||
floor.static_mesh_component.set_static_mesh(floor_mesh)
|
||||
floor.static_mesh_component.set_material(0, floor_mat)
|
||||
log("staged: floor (45 m plane, gray)")
|
||||
log("staged: floor (160 m square, gray, top face Z 0)")
|
||||
else:
|
||||
log("floor spawn failed")
|
||||
|
||||
@@ -118,12 +120,13 @@ try:
|
||||
|
||||
# Hero facade, if the import has run: two views a reviewer needs — straight on
|
||||
# from the north sidewalk, and the oblique street view from further west.
|
||||
hero = unreal.EditorAssetLibrary.load_asset("/Game/Hollywood/ElCapitan/SM_HeroFacade")
|
||||
# The imported mesh spans Y -7..+1250 cm in local space (front plane at -7, the
|
||||
# body behind it) and is centred on X. To put the front plane on the block's
|
||||
# building line the actor goes at Y = building line + 7 cm.
|
||||
# Hero placement in Unreal centimetres (see Geo/manifests/local-origin.md):
|
||||
# front plane on the building line, body behind it.
|
||||
hero_x = -12024.5 + 1302.0
|
||||
hero_y = -1450.0 + 7.0
|
||||
hero = unreal.EditorAssetLibrary.load_asset("/Game/Hollywood/ElCapitan/SM_HeroFacade")
|
||||
# The imported mesh spans Y -7..+1250 cm in local space (front plane at -7, the
|
||||
# body behind it) and is centred on X, so the actor sits at building line + 7 cm.
|
||||
if hero:
|
||||
actor = spawn(unreal.StaticMeshActor, unreal.Vector(hero_x, hero_y, 0.0), "Hero_Facade")
|
||||
if actor:
|
||||
@@ -133,41 +136,57 @@ try:
|
||||
else:
|
||||
log("MISSING: /Game/Hollywood/ElCapitan/SM_HeroFacade (run Tools/ue_hero_facade_import.py)")
|
||||
|
||||
# --- player pawn ---------------------------------------------------------
|
||||
# The review rounds must show the pawn the game actually spawns, not only the
|
||||
# mannequin. Spawn the real character class so its capsule, camera height and
|
||||
# ground contact are what gets rendered.
|
||||
pawn = None
|
||||
char_class = unreal.load_class(None, "/Script/GigLine.GigLineCharacter")
|
||||
if char_class:
|
||||
pawn = spawn(char_class, unreal.Vector(0, 0, 90), "PlayerPawn")
|
||||
if pawn:
|
||||
log("staged: PlayerPawn (AGigLineCharacter) at the spawn point")
|
||||
else:
|
||||
log("MISSING: /Script/GigLine.GigLineCharacter")
|
||||
|
||||
# --- camera list ---------------------------------------------------------
|
||||
# Every camera is a (name, location, target) triple; the look-at rotation is
|
||||
# computed from the pair so a camera cannot drift out of aim when one number
|
||||
# changes. Keep retired shots out of this list entirely.
|
||||
cams = [
|
||||
# wide scene: character, both cubes, floor
|
||||
("overview", unreal.Vector(700, -900, 620), unreal.Vector(0, 300, 80)),
|
||||
# the MPFB mannequin, mid shot
|
||||
("character", unreal.Vector(200, -300, 160), unreal.Vector(0, 0, 85)),
|
||||
# both cubes from the south: contact shadow vs cast shadow
|
||||
("scale-cubes", unreal.Vector(0, -900, 200), unreal.Vector(0, 600, 80)),
|
||||
# the pawn the game spawns, with the grounded cube beside it
|
||||
("player-placement", unreal.Vector(320, -520, 140), unreal.Vector(0, 0, 80)),
|
||||
# low, close on feet and cube base: ground contact must be obvious
|
||||
("ground-contact", unreal.Vector(180, -260, 35), unreal.Vector(0, 40, 20)),
|
||||
# shadow comparison, low angle so both shadows read
|
||||
("shadow-compare", unreal.Vector(-650, -700, 120), unreal.Vector(0, 600, 60)),
|
||||
# the three entry portals at street level
|
||||
# street level, aimed at the base of the centre portal: the portals sit at
|
||||
# Z 0..340 cm behind a 145 cm plinth, so the camera looks slightly down and
|
||||
# targets the portal sill rather than the centre of the elevation.
|
||||
# Standing 25 m out at eye height frames the whole elevation, which is what
|
||||
# the portal detail needs: the portals are small against a 14.5 m façade.
|
||||
("hero-portals", unreal.Vector(hero_x + 150, -4000, 170), unreal.Vector(hero_x + 150, hero_y, 420)),
|
||||
# straight on from the north sidewalk; the building body spans Y -1443..+250
|
||||
("hero-facade-front", unreal.Vector(hero_x + 200, -3200, 420), unreal.Vector(hero_x, hero_y + 400, 760)),
|
||||
# oblique from the north-west, reading the colonnade in depth
|
||||
("hero-facade-oblique", unreal.Vector(hero_x - 2200, -3400, 620), unreal.Vector(hero_x + 300, hero_y, 700)),
|
||||
]
|
||||
shots = spawn(unreal.GigLineShotActor, unreal.Vector(0, 0, 300), "ShotSequencer")
|
||||
if shots:
|
||||
shots.set_editor_property("shot_locations", [
|
||||
unreal.Vector(700, -900, 620),
|
||||
unreal.Vector(200, -300, 160),
|
||||
unreal.Vector(0, -900, 200),
|
||||
# first-person eye height, just south-east of the character: this is the
|
||||
# view a player has at spawn, capsule and camera stack in frame
|
||||
unreal.Vector(120, -260, 165),
|
||||
# straight on from the north sidewalk at eye height. No camera may sit
|
||||
# inside the facade body (Y -1443..+250 cm), so both stand north of the
|
||||
# front plane and look south into the colonnade.
|
||||
unreal.Vector(hero_x + 200, -3200, 420),
|
||||
# oblique from the north-west, reading the colonnade in depth
|
||||
unreal.Vector(hero_x - 2200, -3400, 620),
|
||||
])
|
||||
shots.set_editor_property("shot_rotations", [
|
||||
unreal.MathLibrary.find_look_at_rotation(
|
||||
unreal.Vector(700, -900, 620), unreal.Vector(0, 300, 80)),
|
||||
unreal.MathLibrary.find_look_at_rotation(
|
||||
unreal.Vector(200, -300, 160), unreal.Vector(0, 0, 85)),
|
||||
unreal.MathLibrary.find_look_at_rotation(
|
||||
unreal.Vector(0, -900, 200), unreal.Vector(0, 600, 80)),
|
||||
unreal.MathLibrary.find_look_at_rotation(
|
||||
unreal.Vector(120, -260, 165), unreal.Vector(-200, 600, 90)),
|
||||
unreal.MathLibrary.find_look_at_rotation(
|
||||
unreal.Vector(hero_x + 200, -3200, 420), unreal.Vector(hero_x, hero_y + 400, 760)),
|
||||
unreal.MathLibrary.find_look_at_rotation(
|
||||
unreal.Vector(hero_x - 2200, -3400, 620), unreal.Vector(hero_x + 300, hero_y, 700)),
|
||||
])
|
||||
shots.set_editor_property("shot_names",
|
||||
["overview", "character", "scale-cubes", "first-person",
|
||||
"hero-facade-front", "hero-facade-oblique"])
|
||||
shots.set_editor_property("shot_locations", [c[1] for c in cams])
|
||||
shots.set_editor_property(
|
||||
"shot_rotations",
|
||||
[unreal.MathLibrary.find_look_at_rotation(c[1], c[2]) for c in cams])
|
||||
shots.set_editor_property("shot_names", [c[0] for c in cams])
|
||||
shots.set_editor_property("quit_when_done", True)
|
||||
log("staged: ShotSequencer with 6 cameras")
|
||||
log(f"staged: ShotSequencer with {len(cams)} cameras: {', '.join(c[0] for c in cams)}")
|
||||
except Exception as exc: # noqa
|
||||
log(f"staging failed: {exc!r}")
|
||||
|
||||
|
||||
Reference in new issue
Block a user