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:
1 parent
cef87b3d31
commit
985dfcbac7
36 files changed
+178
-68
No files matched your search
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user