npc: AGigLineNPCPerson prefab + stable-named screenshots

- New C++ AGigLineNPCPerson: reusable NPC/pedestrian prefab built on the MPFB
  human. ACharacter capsule half-height 83 cm (total 1.66 m, head top ~1.66 m
  so a 1.60 m camera doesn't clip), the character skeletal mesh on the built-in
  mesh as the visible body (feet on Z 0), AutoPossessAI for 0.5.0 pedestrians.
  Staged at Z 0 in the review scene; captured as review-npc-prefab.png.
- AGigLineShotActor now names screenshots by stable camera name (no list-index
  prefix): inserting or reordering cameras no longer renumbers files or orphans
  the old ones. Re-rendered all review/demo shots with stable names.
- ue_build_review_map.py: chmod the target .umap before save_map (git marks maps
  444 on checkout, silently making save_map return False and dropping stages).
- Screenshots/README.md, ROADMAP, TODO updated for the prefab + stable names.
- DemoMap.umap rebuilt by the render pipeline (north buildings + demo cameras).
This commit is contained in:
zwitschi committed 2026-11-07 15:28:42 +01:00
1 parent cef87b3d31
commit 985dfcbac7
36 files changed
+178 -68

No files matched your search

Binary file not shown.
Binary file not shown.
@@ -0,0 +1,34 @@
#include "GigLineNPCPerson.h"
#include "Components/CapsuleComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "Engine/SkeletalMesh.h"
AGigLineNPCPerson::AGigLineNPCPerson()
{
// The MPFB human is ~1.66 m tall, ~0.43 m wide. Half-height 83 cm leaves
// the head top at ~1.66 m, so a 1.60 m camera does not clip it. Radius
// ~35 cm accommodates the relaxed idle pose (arms at the sides).
GetCapsuleComponent()->InitCapsuleSize(35.0f, 83.0f);
GetCapsuleComponent()->SetRelativeLocation(FVector(0.0f, 0.0f, 83.0f));
// Visible body: the imported MPFB human on ACharacter's built-in mesh
// component, feet at Z 0 (capsule base lowered to the floor).
USkeletalMeshComponent* Mesh = GetMesh();
Mesh->SetRelativeLocation(FVector(0.0f, 0.0f, -83.0f));
Mesh->SetRelativeRotation(FRotator(0.0f, -90.0f, 0.0f));
Mesh->SetCastShadow(true);
static ConstructorHelpers::FObjectFinder<USkeletalMesh> MeshAsset(
TEXT("/Game/Test/Character/character"));
if (MeshAsset.Succeeded())
{
Mesh->SetSkeletalMeshAsset(MeshAsset.Object);
Mesh->SetSkeletalMesh(MeshAsset.Object);
}
// An NPC pawn has no player input; hand it to AI when it is spawned into
// the world (the 0.5.0 pedestrian navigation will drive it).
AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned;
bUseControllerRotationYaw = false;
}
@@ -0,0 +1,32 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "GigLineNPCPerson.generated.h"
/**
* Reusable NPC/pedestrian prefab built on the MPFB human asset.
*
* Deliberately NOT the 0.1.0 player (which is AGigLineCharacter, a capsule +
* camera). This is the visible-body template for future NPCs/pedestrians
* (0.5.0): ACharacter's collision capsule sized to the ~1.66 m MPFB human,
* with the character skeletal mesh on the built-in mesh component as the
* visible body, feet at Z 0.
*
* Head-height guarantee: capsule half-height 83 cm (total 1.66 m), so the head
* top sits at ~1.66 m; a camera/view at 1.60 m sits just below eye level and
* does not clip the head or neck. Set HeadHeightCm after observing the posed
* mesh if the eye socket lands elsewhere.
*/
UCLASS()
class GIGLINE_API AGigLineNPCPerson : public ACharacter
{
GENERATED_BODY()
public:
AGigLineNPCPerson();
/** Observed head height (cm above Z 0), used to verify camera clearance. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "NPC")
float HeadHeightCm = 155.f;
};
@@ -27,8 +27,12 @@ void AGigLineShotActor::Tick(float DeltaSeconds)
if (SettleCountdown <= 0.f)
{
bWaitingForSettle = false;
const FString FileName = FString::Printf(TEXT("review-%02d-%s"), CurrentShot,
CurrentShot < ShotNames.Num() ? *ShotNames[CurrentShot] : *FString::FromInt(CurrentShot));
// Use the stable custom name only (no list-index prefix): inserting or
// reordering cameras must not renumber files and orphan the old ones.
const FString Name = CurrentShot < ShotNames.Num()
? ShotNames[CurrentShot]
: FString::FromInt(CurrentShot);
const FString FileName = FString::Printf(TEXT("review-%s"), *Name);
// Resolution is the game window's; the runner passes -ResX/-ResY.
FScreenshotRequest::RequestScreenshot(FileName, false, false);
bWaitingForScreenshot = true;
+1 -1
View File
@@ -28,7 +28,7 @@ Workstation, geo pipeline, and engine validation are done. The art pipeline has
**Geographic data (complete, with blockout detail open):** the OSM extract, address, footprints, demo bounds, EPSG:26911 frame with a recorded origin, and the 3DEP 1 m DEM are verified and committed. The meter→centimetre conversion lives in one function, and every exporter must call it. Block buildings still need height data for three placeholders and cleaning or detailing of the Blosm blockout.
**Review and character (decision):** the review scene is the staging used for all visual approval. Its scope is the character's ground contact, the camera list, and the façade detail shots, and nothing in asset production or gameplay continues past it until these shots pass. The shot list is in `Screenshots/README.md`. Coordinator decision 2026-11-07: **`0.1.0` ships first-person only**, a capsule with a camera and no visible player body. The MPFB character asset (idle pose, warm skin) is the template for later **NPCs** (`0.2.0` body/camera toggle, `0.5.0` pedestrians). It stays a standalone character prefab, not wired into the `AGigLineCharacter` pawn.
**Review and character (decision):** the review scene is the staging used for all visual approval. Its scope is the character's ground contact, the camera list, and the façade detail shots, and nothing in asset production or gameplay continues past it until these shots pass. The shot list is in `Screenshots/README.md`. Coordinator decision 2026-11-07: **`0.1.0` ships first-person only**, a capsule with a camera and no visible player body. The MPFB character asset (idle pose, warm skin) is the template for later **NPCs** (`0.2.0` body/camera toggle, `0.5.0` pedestrians). It is now a concrete reusable prefab, `AGigLineNPCPerson` (collision capsule + visible body, feet on Z 0), kept standalone and not wired into the `AGigLineCharacter` pawn.
**Asset production:** the scale test and the `ue_metric_v1` export and import presets are established. The hero façade first pass is built and screenshot-approved; the north-side buildings (TCL Chinese Theatre, Madame Tussaud's) are staged. Open: reference collection for the door recess and the night frame, the surrounding block frontage, sidewalks, roads and collision, and materials for all assets.
+19 -14
View File
@@ -27,19 +27,24 @@ and exits — about a minute. The camera list lives in
## Review-map shots
All ☑ approved 2026-11-07 unless noted. Click an image for the full-size PNG.
All ☑ approved 2026-11-07 unless noted. `review-npc-prefab` is new (☐ pending).
> Naming: shots use their stable `Tools/ue_build_review_map.py` camera name (no
> index prefix), so adding or reordering cameras never renumbers files or
> orphans the old ones. Click an image for the full-size PNG.
| File | Preview | View | What it shows |
| --- | --- | --- | --- |
| `review-00-overview.png` | [<img src="review-00-overview.png" alt="overview" width="200">](review-00-overview.png) | 7 m up, NE | Whole review layout: character + both cubes on the floor |
| `review-01-character.png` | [<img src="review-01-character.png" alt="character" width="200">](review-01-character.png) | eye height, south | MPFB mannequin, idle pose + warm skin; feet meet the plane |
| `review-02-scale-cubes.png` | [<img src="review-02-scale-cubes.png" alt="scale cubes" width="200">](review-02-scale-cubes.png) | south | Floating vs grounded cube: cast vs contact shadow |
| `review-03-player-placement.png` | [<img src="review-03-player-placement.png" alt="player placement" width="200">](review-03-player-placement.png) | spawn | The `AGigLineCharacter` pawn, capsule height and landing |
| `review-04-ground-contact.png` | [<img src="review-04-ground-contact.png" alt="ground contact" width="200">](review-04-ground-contact.png) | knee height, feet | Floating/sinking character is obvious here |
| `review-05-shadow-compare.png` | [<img src="review-05-shadow-compare.png" alt="shadow compare" width="200">](review-05-shadow-compare.png) | low angle | Detached (floating) vs touching (grounded) shadows |
| `review-06-hero-portals.png` | [<img src="review-06-hero-portals.png" alt="hero portals" width="200">](review-06-hero-portals.png) | 8 m, eye height | Three genuine 1.2 m portal recesses with flights and plinth |
| `review-07-hero-facade-front.png` | [<img src="review-07-hero-facade-front.png" alt="hero facade front" width="200">](review-07-hero-facade-front.png) | road side, straight-on | Hero façade elevation and column rhythm |
| `review-08-hero-facade-oblique.png` | [<img src="review-08-hero-facade-oblique.png" alt="hero facade oblique" width="200">](review-08-hero-facade-oblique.png) | north-west | Body depth and column line standing proud of the mass |
| `review-overview.png` | [<img src="review-overview.png" alt="overview" width="200">](review-overview.png) | 7 m up, NE | Whole review layout: character + both cubes on the floor |
| `review-character.png` | [<img src="review-character.png" alt="character" width="200">](review-character.png) | eye height, south | MPFB mannequin, idle pose + warm skin; feet meet the plane |
| `review-scale-cubes.png` | [<img src="review-scale-cubes.png" alt="scale cubes" width="200">](review-scale-cubes.png) | south | Floating vs grounded cube: cast vs contact shadow |
| `review-player-placement.png` | [<img src="review-player-placement.png" alt="player placement" width="200">](review-player-placement.png) | spawn | The `AGigLineCharacter` pawn, capsule height and landing |
| `review-npc-prefab.png` | [<img src="review-npc-prefab.png" alt="npc prefab" width="200">](review-npc-prefab.png) | mid, west | The `AGigLineNPCPerson` prefab: collision capsule + visible MPFB body, feet on Z 0 (**new 2026-11-07**) |
| `review-ground-contact.png` | [<img src="review-ground-contact.png" alt="ground contact" width="200">](review-ground-contact.png) | knee height, feet | Floating/sinking character is obvious here |
| `review-shadow-compare.png` | [<img src="review-shadow-compare.png" alt="shadow compare" width="200">](review-shadow-compare.png) | low angle | Detached (floating) vs touching (grounded) shadows |
| `review-hero-portals.png` | [<img src="review-hero-portals.png" alt="hero portals" width="200">](review-hero-portals.png) | 8 m, eye height | Three genuine 1.2 m portal recesses with flights and plinth |
| `review-hero-facade-front.png` | [<img src="review-hero-facade-front.png" alt="hero facade front" width="200">](review-hero-facade-front.png) | road side, straight-on | Hero façade elevation and column rhythm |
| `review-hero-facade-oblique.png` | [<img src="review-hero-facade-oblique.png" alt="hero facade oblique" width="200">](review-hero-facade-oblique.png) | north-west | Body depth and column line standing proud of the mass |
## Demo-map views
@@ -47,10 +52,10 @@ Rendered from `/Game/Hollywood/DemoMap`, the walkable level. Click an image for
| File | Preview | Approval | What it shows |
| --- | --- | --- | --- |
| `demo/review-00-demo-spawn-view.png` | [<img src="demo/review-00-demo-spawn-view.png" alt="spawn view" width="200">](demo/review-00-demo-spawn-view.png) | ☑ | Spawn view: north sidewalk, the hero façade across the road |
| `demo/review-01-demo-street-level.png` | [<img src="demo/review-01-demo-street-level.png" alt="street level" width="200">](demo/review-01-demo-street-level.png) | ☑ | Street level: portals, flights, banners, colonnade |
| `demo/review-02-demo-crossing.png` | [<img src="demo/review-02-demo-crossing.png" alt="crossing" width="200">](demo/review-02-demo-crossing.png) | needs review | From the west, looking along the block (foreground blocking) |
| `demo/review-03-demo-north-buildings.png` | [<img src="demo/review-03-demo-north-buildings.png" alt="north buildings" width="200">](demo/review-03-demo-north-buildings.png) | ☑ | North-side background buildings (TCL, Tussaud's) across the Blvd |
| `demo/review-demo-spawn-view.png` | [<img src="demo/review-demo-spawn-view.png" alt="spawn view" width="200">](demo/review-demo-spawn-view.png) | ☑ | Spawn view: north sidewalk, the hero façade across the road |
| `demo/review-demo-street-level.png` | [<img src="demo/review-demo-street-level.png" alt="street level" width="200">](demo/review-demo-street-level.png) | ☑ | Street level: portals, flights, banners, colonnade |
| `demo/review-demo-crossing.png` | [<img src="demo/review-demo-crossing.png" alt="crossing" width="200">](demo/review-demo-crossing.png) | needs review | From the west, looking along the block (foreground blocking) |
| `demo/review-demo-north-buildings.png` | [<img src="demo/review-demo-north-buildings.png" alt="north buildings" width="200">](demo/review-demo-north-buildings.png) | ☑ | North-side background buildings (TCL, Tussaud's) across the Blvd |
## What to look for
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10 -9
View File
@@ -61,11 +61,11 @@ Owner: this session. Scope: the review scene used for all visual approval — th
- [x] Put the character on the ground rather than floating. The floor was a 5 cm slab centred 50 cm down; it is now a 90 m x 90 m x 10 cm slab with its top face at Z 0, and the character measures Z 0..83 cm — feet on the plane (`Screenshots/README.md`).
- [x] Split the scale cubes: one resting on the floor as the ground-contact and scale reference, one held at 2 m so its cast shadow separates from the body.
- [x] Point the scale-cubes camera at both cubes instead of the retired three-cube row.
- [x] **Character placement shot**: `review-03-player-placement` shows the pawn (`AGigLineCharacter`) staged by `Tools/ue_build_review_map.py` with a cube behind it. Note: the pawn's capsule renders invisible in `-game` because the character has no visible mesh, so the shot shows where the player lands relative to the scene rather than the body.
- [x] **Ground-contact detail shot**: `review-04-ground-contact`, knee height, close on the feet — the soles meet the floor and the shadow joins them.
- [x] **Shadow-comparison detail shot**: `review-05-shadow-compare`, both cubes in one frame from a low angle; the floating cube's shadow is detached, the grounded one's touches.
- [x] **Detail shot of the hero façade portals**: `review-06-hero-portals` from 8 m at eye height now fills the frame with all three doorways. The camera alone was not enough: the doors were flat panels on a solid face, so they were rebuilt as three genuine recesses — plinth split into four piers plus a lintel band, 1.2 m reveal, stone jambs and lintels standing 0.10 m proud, three mullions each. Facade bounds are now exactly Z 0..14.50 m; a jamb overhang had been sinking the model 0.15 m into the ground.
- [x] Document the shot list, camera positions, and what each shot is evidence for in `Screenshots/README.md`; nine shots, each with an approval line.
- [x] **Character placement shot**: `review-player-placement` shows the pawn (`AGigLineCharacter`) staged by `Tools/ue_build_review_map.py` with a cube behind it. Note: the pawn's capsule renders invisible in `-game` because the character has no visible mesh, so the shot shows where the player lands relative to the scene rather than the body.
- [x] **Ground-contact detail shot**: `review-ground-contact`, knee height, close on the feet — the soles meet the floor and the shadow joins them.
- [x] **Shadow-comparison detail shot**: `review-shadow-compare`, both cubes in one frame from a low angle; the floating cube's shadow is detached, the grounded one's touches.
- [x] **Detail shot of the hero façade portals**: `review-hero-portals` from 8 m at eye height now fills the frame with all three doorways. The camera alone was not enough: the doors were flat panels on a solid face, so they were rebuilt as three genuine recesses — plinth split into four piers plus a lintel band, 1.2 m reveal, stone jambs and lintels standing 0.10 m proud, three mullions each. Facade bounds are now exactly Z 0..14.50 m; a jamb overhang had been sinking the model 0.15 m into the ground.
- [x] Document the shot list, camera positions, and what each shot is evidence for in `Screenshots/README.md`; shots use stable names with an approval line (10 review + 4 demo).
- [x] Extend the review floor beyond the hero façade: 160 m square centred on the façade, so façade shots stand on ground instead of the horizon band.
- [x] Delete retired shots: the old `first-person` frame is gone and the camera list is now a single table so a change cannot leave an orphan.
@@ -75,14 +75,15 @@ The MPFB character asset is planned as the NPC template (see `ROADMAP.md`). Keep
- [x] Give the MPFB character asset a standing idle pose so review and NPC shots show a person, not an A-pose bind. Done: `Tools/mpfb_character_export.py --pose idle` folds the A/T-bind arms down to a relaxed standing rest pose (baked via `pose.armature_apply` before export; `upperarm01.L` rest z −0.71 → −1.91 rad), re-exported, re-imported (138 bones), rendered in `review-01-character`.
- [x] Bake a second skin tone or clothing layer, so the character does not read as a grey mannequin in shots. Done: the v2-skin bake came out **black** and slow at 1024², so we synthesize a warm skin-tone diffuse directly (`Tools/mpfb_character_export.py` `make_diffuse`, with a darker shorts-suggestive bottom band) via a stdlib/numpy PNG writer. Character reads warm, not grey. Screenshot approved (`Screenshots/review-01-character`).
- [ ] (open) Keep the character as a reusable NPC prefab: a visible body, a collision capsule, and a head-height check that the camera does not clip at 1.60 m — for when NPCs/pedestrians are wired in (`0.2.0+`), not the `0.1.0` player.
- [x] Keep the character as a reusable NPC prefab: a visible body, a collision capsule, and a head-height check that the camera does not clip at 1.60 m — for when NPCs/pedestrians are wired in (`0.2.0+`), not the `0.1.0` player. Done 2026-11-07: `AGigLineNPCPerson` (C++), ACharacter with capsule half-height 83 cm / total 1.66 m (head at ~1.66 m, so a 1.60 m camera does not clip), the MPFB human on the built-in mesh as the visible body, `AutoPossessAI` for pedestrians; confirmed spawned feet-on-Z-0 and rendered in `Screenshots/review-npc-prefab` (☐ pending approval).
- [x] Screenshots use stable camera names (no index prefix), so inserting a shot no longer renumbers/ orphans files; `AGigLineShotActor` + `Screenshots/README.md` updated.
### Asset production
- [x] Establish a consistent scale test, named export presets, and repeatable import settings. Scale test = the three-cube calibration scene (`Art/blender/scaletest/`, regenerable via `Tools/scale_test_export.py`); named export preset `ue_metric_v1` (FBX settings in that script); named import preset `ue_metric_v1` (`FbxImportUI` settings in `Tools/ue_scale_test_import.py`). Both scripts are the templates for production asset export/import.
- [-] Collect reference photography for manual façade work. Local only, never committed: `Art/reference/` is gitignored. **72 images in eleven folders**: hero façades to 4k, the El Capitan Theatre exterior series, premiere-night staging, Ovation Hollywood, the north side, and the Lee Drug neighbour. Gaps largely closed by the Flickr/web-search pass: the hero entrance is now documented (three portals with individual short flights — the inherited "eight steps, 12 m wide" is overturned), and the 6806–6822 retail run appears in an oblique 2013 frame. Still missing: a clean isolated frame of the door recess and a night frame of 6840 itself.
- [x] Download reference photography for the two north-side buildings inside the 50 m buffer — TCL Chinese Theatre (OSM way 424105908, 6925 Hollywood Blvd) and Madame Tussaud's (way 424105889, 6933 Hollywood Blvd). Done 2026-11-06 with `Tools/commons_fetch.py` against the Wikimedia Commons API: eleven frames in the local `Art/reference/north-chinese/` and `Art/reference/north-tussauds/`, provenance in each `sidecar.json`, nothing committed.
- [x] Model hero façade for the El Capitan Entertainment Centre site. **Second pass built 2026-11-07** (proportions recalibrated from the 2009 photograph: entablature 3.4 m, parapet 2.2 m, architrave and cornice bands, square pedestals — the first pass had 5.7 m of blank wall above the capitals and read as a warehouse). **First pass built 2026-11-07** (`Tools/hero_facade_build.py` → `Art/blender/hero/hero-facade-2026-11-07.blend` + JSON part report with evidence per part → `Tools/ue_hero_facade_import.py` → `/Game/Hollywood/ElCapitan/SM_HeroFacade`, 1892 tris, 4 materials, placed on the measured building line). Six columns at 4.96 m over the 25.75 m frontage, plinth, three portal flights (5 risers, not the old 8), entablature 2.2 m, parapet 1.6 m with motto band and medallions. **Screenshot approved** (`Screenshots/review-06` portals, `review-07/08` facade). Next pass: banner and window placement, then materials.
- [x] Model hero façade for the El Capitan Entertainment Centre site. **Second pass built 2026-11-07** (proportions recalibrated from the 2009 photograph: entablature 3.4 m, parapet 2.2 m, architrave and cornice bands, square pedestals — the first pass had 5.7 m of blank wall above the capitals and read as a warehouse). **First pass built 2026-11-07** (`Tools/hero_facade_build.py` → `Art/blender/hero/hero-facade-2026-11-07.blend` + JSON part report with evidence per part → `Tools/ue_hero_facade_import.py` → `/Game/Hollywood/ElCapitan/SM_HeroFacade`, 1892 tris, 4 materials, placed on the measured building line). Six columns at 4.96 m over the 25.75 m frontage, plinth, three portal flights (5 risers, not the old 8), entablature 2.2 m, parapet 1.6 m with motto band and medallions. **Screenshot approved** (`Screenshots/review-hero-portals`, `review-hero-facade-front/oblique`). Next pass: banner and window placement, then materials.
- [ ] Model surrounding block frontage.
- [x] Model simplified background buildings directly across Hollywood Boulevard. Done 2026-11-07, the two in-scope north-side buildings — TCL Chinese Theatre (SM_TCL_Chinese_Theatre) and Madame Tussaud's (SM_Madame_Tussauds) — taken from the verified OSM blockout volumes and exported with `ue_metric_v1`, with a Y-mirror so they land north of Hollywood Blvd across the street from the hero (TCL spans Unreal Y 1802..9431, Tussaud's 1888..7586; road centreline ≈ 0, hero façade at Y −1450). Staged in the DemoMap as `North_TCL_Chinese` / `North_Madame_Tussauds`; demo shot `review-03-demo-north-buildings` captured. Simple flat facade materials (surfaces are the `0.1.4` patch).
- [-] Build sidewalks, roads, and collision meshes. Terrain, road, sidewalks and kerbs exist (`Art/blender/terrain/`, `street/`) and are assembled in `site/site-2026-11-06.blend`; collision and details (crossing markings, kerb radii, aprons) are not built. Ground must follow the DEM: 3.94 m fall along the block, ~2 % crown between the gutters at ±10–11 m from the centreline, north sidewalk higher than south. Kerb height is an unresolved assumption — the DEM does not resolve it (`Geo/verification/2026-11-06-cross-sections.md`).
@@ -174,7 +175,7 @@ Suggested blender skills: **procedural-modeling** + **geometry-nodes** (the faç
- [x] Generate MPFB human base mesh; export baked materials and deform skeleton. Done in bootstrap: idle-pose 19 158-vert human with a 137-bone standard rig, `Tools/mpfb_character_export.py` (now `--pose idle` + warm `make_diffuse`).
- [x] Import character into Unreal; validate skeleton, scale, and materials. Done: `/Game/Test/Character` — `SkeletalMesh` (138 bones), `Skeleton`, warm `M_Character_Export` material with baked `T_Character_Diffuse`.
- [ ] Promote the character asset into a reusable NPC prefab (visible body, collision capsule, idle pose) ready for pedestrians (`0.5.0`) once the third-person body lands.
- [x] Promote the character asset into a reusable NPC prefab (visible body, collision capsule, idle pose) ready for pedestrians (`0.5.0`) once the third-person body lands. Done 2026-11-07: `AGigLineNPCPerson` (see the 0.1.0 Character-development item); `0.5.0` reuses it as the pedestrian base.
- [ ] Create basic idle/walk animation set.
- [ ] Verify animation plays correctly on the imported rig.
@@ -293,7 +294,7 @@ Suggested blender skills: **procedural-modeling** + **geometry-nodes** (the faç
### Simulation
- [ ] Add pedestrian characters with navigation, reusing the idle-pose character asset as the NPC prefab (`/Game/Test/Character`).
- [ ] Add pedestrian characters with navigation, using `AGigLineNPCPerson` (the reusable NPC prefab) as the base, driving it via AI/`AutoPossessAI`.
- [ ] Implement crosswalk behavior (pedestrians use the designated crossing).
- [ ] Add limited ambient traffic on the street network.
- [ ] Optimize simulation cost to stay within frame budget.
+31
View File
@@ -25,6 +25,20 @@ def log(msg):
lines.append(str(msg))
def ensure_writable(path):
# A packed .umap left read-only (git sets 644->444 on checkout, or the
# editor re-flags it) makes save_map silently return False with no error.
# chmod u+w it so the staged camera list and actors actually persist.
p = os.path.join(unreal.Paths.project_dir(), path.replace("/Game/", "Content/"))
try:
mode = os.stat(p).st_mode & 0o777
if mode & 0o200 == 0:
os.chmod(p, 0o644)
log(f"map writable: chmod u+w {p} (was {oct(mode)})")
except FileNotFoundError:
pass
def spawn(cls, loc, label=None, scale=None, rot=None):
a = unreal.EditorLevelLibrary.spawn_actor_from_class(cls, loc)
if a is None:
@@ -149,6 +163,18 @@ try:
else:
log("MISSING: /Script/GigLine.GigLineCharacter")
# --- NPC prefab -----------------------------------------------------------
# The reusable NPC person: a collision capsule + visible MPFB body, standing
# feet on Z 0, placed clear of the pawn so the prefab reads on its own.
npc = None
npc_class = unreal.load_class(None, "/Script/GigLine.GigLineNPCPerson")
if npc_class:
npc = spawn(npc_class, unreal.Vector(-4500, 300, 0), "NPC_Person")
if npc:
log("staged: NPC_Person (AGigLineNPCPerson) at Z 0")
else:
log("MISSING: /Script/GigLine.GigLineNPCPerson")
# --- 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
@@ -162,6 +188,9 @@ try:
("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)),
# the NPC prefab: capsule + visible body, feet on Z 0, at double scale
# distance because it stands off to the west of the main staging
("npc-prefab", unreal.Vector(-4200, 600, 160), unreal.Vector(-4500, 300, 90)),
# 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
@@ -214,6 +243,7 @@ try:
# quit after the demo shots so a dedicated DemoMap capture run
# terminates cleanly (render_screenshots.sh runs both maps).
seq.set_editor_property("quit_when_done", True)
ensure_writable("/Game/Hollywood/DemoMap")
saved = unreal.EditorLoadingAndSavingUtils.save_map(
unreal.EditorLevelLibrary.get_editor_world(), "/Game/Hollywood/DemoMap")
log(f"demo map staged: {len(demo_shots)} cameras, save {saved}")
@@ -239,6 +269,7 @@ except Exception as exc: # noqa
# --- save --------------------------------------------------------------------
try:
ensure_writable(MAP_PATH)
world = unreal.EditorLevelLibrary.get_editor_world()
saved = unreal.EditorLoadingAndSavingUtils.save_map(world, MAP_PATH)
log(f"save_map {MAP_PATH}: {saved}")