Improve investor visual recovery pass

This commit is contained in:
2026-05-19 18:03:15 -07:00
parent c742a172da
commit d59f613e2b
10 changed files with 467 additions and 343 deletions
@@ -12,10 +12,13 @@
#include "AgrarianPersistenceSubsystem.h"
#include "AgrarianShelterActor.h"
#include "AgrarianSurvivalComponent.h"
#include "Camera/CameraActor.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/StaticMeshComponent.h"
#include "EnhancedInputSubsystems.h"
#include "Engine/LocalPlayer.h"
#include "Engine/SkeletalMesh.h"
#include "Engine/StaticMesh.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "InputCoreTypes.h"
@@ -92,6 +95,58 @@ namespace
? TEXT("/Game/Agrarian/Characters/Materials/M_AGR_CharacterProxy_Workwear_Female.M_AGR_CharacterProxy_Workwear_Female")
: TEXT("/Game/Agrarian/Characters/Materials/M_AGR_CharacterProxy_Workwear_Male.M_AGR_CharacterProxy_Workwear_Male");
}
UStaticMeshComponent* EnsureMvpPresentationComponent(
AAgrarianGameCharacter* Character,
const FName ComponentName,
UStaticMesh* Mesh,
UMaterialInterface* Material,
const FVector& RelativeLocation,
const FRotator& RelativeRotation,
const FVector& RelativeScale)
{
if (!Character || !Mesh)
{
return nullptr;
}
UStaticMeshComponent* Component = nullptr;
TArray<UStaticMeshComponent*> ExistingComponents;
Character->GetComponents<UStaticMeshComponent>(ExistingComponents);
for (UStaticMeshComponent* ExistingComponent : ExistingComponents)
{
if (ExistingComponent && ExistingComponent->GetFName() == ComponentName)
{
Component = ExistingComponent;
break;
}
}
if (!Component)
{
Component = NewObject<UStaticMeshComponent>(Character, ComponentName);
if (!Component)
{
return nullptr;
}
Component->SetupAttachment(Character->GetRootComponent());
Component->RegisterComponent();
Character->AddInstanceComponent(Component);
}
Component->SetStaticMesh(Mesh);
if (Material)
{
Component->SetMaterial(0, Material);
}
Component->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Component->SetGenerateOverlapEvents(false);
Component->SetRelativeLocation(RelativeLocation);
Component->SetRelativeRotation(RelativeRotation);
Component->SetRelativeScale3D(RelativeScale);
Component->SetHiddenInGame(false);
return Component;
}
}
void AAgrarianGamePlayerController::BeginPlay()
@@ -102,8 +157,7 @@ void AAgrarianGamePlayerController::BeginPlay()
{
if (MvpFrontendStartupDelaySeconds > 0.0f)
{
SetIgnoreMoveInput(true);
SetIgnoreLookInput(true);
SetMvpFrontendPresentationActive(true);
SetInputMode(FInputModeUIOnly());
bShowMouseCursor = false;
GetWorldTimerManager().SetTimer(
@@ -139,6 +193,22 @@ void AAgrarianGamePlayerController::BeginPlay()
}
}
void AAgrarianGamePlayerController::AcknowledgePossession(APawn* P)
{
Super::AcknowledgePossession(P);
if (!IsLocalPlayerController())
{
return;
}
ApplyMvpCharacterProxyToPawn();
if (bMvpFrontendPresentationActive)
{
SetMvpFrontendPresentationActive(true);
}
}
void AAgrarianGamePlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
@@ -204,6 +274,7 @@ void AAgrarianGamePlayerController::ShowMvpFrontend()
{
MvpFrontendWidget->AddToPlayerScreen(10);
}
SetMvpFrontendPresentationActive(true);
SetInputMode(FInputModeUIOnly().SetWidgetToFocus(MvpFrontendWidget->TakeWidget()).SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock));
bShowMouseCursor = true;
SetIgnoreMoveInput(true);
@@ -241,6 +312,7 @@ void AAgrarianGamePlayerController::ShowMvpPauseMenu()
}
MvpFrontendWidget->SetActiveScreen(EAgrarianMvpFrontendScreen::MainMenu);
SetMvpFrontendPresentationActive(true);
SetInputMode(FInputModeUIOnly().SetWidgetToFocus(MvpFrontendWidget->TakeWidget()).SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock));
bShowMouseCursor = true;
SetIgnoreMoveInput(true);
@@ -275,6 +347,132 @@ void AAgrarianGamePlayerController::HandleMvpEscapeInput()
ShowMvpPauseMenu();
}
void AAgrarianGamePlayerController::SetMvpFrontendPresentationActive(bool bNewActive)
{
bMvpFrontendPresentationActive = bNewActive;
SetIgnoreMoveInput(bNewActive);
SetIgnoreLookInput(bNewActive);
APawn* ControlledPawn = GetPawn();
if (ControlledPawn)
{
ControlledPawn->SetActorHiddenInGame(bNewActive);
ControlledPawn->SetActorEnableCollision(!bNewActive);
if (ACharacter* ControlledCharacter = Cast<ACharacter>(ControlledPawn))
{
if (UCharacterMovementComponent* MovementComponent = ControlledCharacter->GetCharacterMovement())
{
if (bNewActive)
{
MovementComponent->DisableMovement();
}
else
{
MovementComponent->SetMovementMode(MOVE_Walking);
}
}
}
}
CacheAndApplyMvpHudSuppression(bNewActive);
if (bNewActive)
{
CreateOrUpdateMvpFrontendCamera();
if (MvpFrontendCameraActor)
{
SetViewTarget(MvpFrontendCameraActor);
}
return;
}
if (ControlledPawn)
{
SetViewTarget(ControlledPawn);
}
}
void AAgrarianGamePlayerController::CreateOrUpdateMvpFrontendCamera()
{
UWorld* World = GetWorld();
if (!World)
{
return;
}
const APawn* ControlledPawn = GetPawn();
const FVector TargetLocation = ControlledPawn
? ControlledPawn->GetActorLocation() + FVector(0.0f, 0.0f, 95.0f)
: GroundZeroDeveloperTravelHomeLocation;
const FVector CameraLocation = TargetLocation + FVector(-620.0f, -520.0f, 260.0f);
const FRotator CameraRotation = (TargetLocation - CameraLocation).Rotation();
if (!MvpFrontendCameraActor)
{
FActorSpawnParameters SpawnParameters;
SpawnParameters.Owner = this;
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
MvpFrontendCameraActor = World->SpawnActor<ACameraActor>(ACameraActor::StaticClass(), CameraLocation, CameraRotation, SpawnParameters);
if (MvpFrontendCameraActor)
{
MvpFrontendCameraActor->SetActorHiddenInGame(true);
}
return;
}
MvpFrontendCameraActor->SetActorLocationAndRotation(CameraLocation, CameraRotation);
}
void AAgrarianGamePlayerController::CacheAndApplyMvpHudSuppression(bool bSuppress)
{
AAgrarianDebugHUD* AgrarianHUD = GetHUD<AAgrarianDebugHUD>();
if (!AgrarianHUD)
{
return;
}
if (bSuppress)
{
if (!bCachedMvpHudState)
{
bCachedShowDebugHUD = AgrarianHUD->bShowDebugHUD;
bCachedShowMvpHudFrame = AgrarianHUD->bShowMvpHudFrame;
bCachedShowCriticalStatsHUD = AgrarianHUD->bShowCriticalStatsHUD;
bCachedShowInventoryHUD = AgrarianHUD->bShowInventoryHUD;
bCachedShowCraftingHUD = AgrarianHUD->bShowCraftingHUD;
bCachedShowInteractionPrompt = AgrarianHUD->bShowInteractionPrompt;
bCachedShowDeathRespawnUI = AgrarianHUD->bShowDeathRespawnUI;
bCachedShowDebugDevMenu = AgrarianHUD->bShowDebugDevMenu;
bCachedMvpHudState = true;
}
AgrarianHUD->bShowDebugHUD = false;
AgrarianHUD->bShowMvpHudFrame = false;
AgrarianHUD->bShowCriticalStatsHUD = false;
AgrarianHUD->bShowInventoryHUD = false;
AgrarianHUD->bShowCraftingHUD = false;
AgrarianHUD->bShowInteractionPrompt = false;
AgrarianHUD->bShowDeathRespawnUI = false;
AgrarianHUD->bShowDebugDevMenu = false;
return;
}
if (bCachedMvpHudState)
{
AgrarianHUD->bShowDebugHUD = bCachedShowDebugHUD;
AgrarianHUD->bShowMvpHudFrame = bCachedShowMvpHudFrame;
AgrarianHUD->bShowCriticalStatsHUD = bCachedShowCriticalStatsHUD;
AgrarianHUD->bShowInventoryHUD = bCachedShowInventoryHUD;
AgrarianHUD->bShowCraftingHUD = bCachedShowCraftingHUD;
AgrarianHUD->bShowInteractionPrompt = bCachedShowInteractionPrompt;
AgrarianHUD->bShowDeathRespawnUI = bCachedShowDeathRespawnUI;
AgrarianHUD->bShowDebugDevMenu = bCachedShowDebugDevMenu;
bCachedMvpHudState = false;
}
}
void AAgrarianGamePlayerController::ApplyMvpCharacterProxyToPawn()
{
AAgrarianGameCharacter* AgrarianCharacter = GetPawn<AAgrarianGameCharacter>();
@@ -297,6 +495,61 @@ void AAgrarianGamePlayerController::ApplyMvpCharacterProxyToPawn()
MeshComponent->SetMaterial(MaterialIndex, ProxyMaterial);
}
}
UStaticMesh* ChamferMesh = LoadObject<UStaticMesh>(
nullptr,
TEXT("/Game/Agrarian/Environment/PlaceholderMeshes/SM_AGR_Placeholder_ChamferCube.SM_AGR_Placeholder_ChamferCube"));
UStaticMesh* CubeMesh = LoadObject<UStaticMesh>(
nullptr,
TEXT("/Game/Agrarian/Environment/PlaceholderMeshes/SM_AGR_Placeholder_Cube.SM_AGR_Placeholder_Cube"));
UStaticMesh* CylinderMesh = LoadObject<UStaticMesh>(
nullptr,
TEXT("/Game/Agrarian/Environment/PlaceholderMeshes/SM_AGR_Placeholder_Cylinder.SM_AGR_Placeholder_Cylinder"));
UMaterialInterface* WorkwearMaterial = LoadObject<UMaterialInterface>(nullptr, GetMvpCharacterProxyMaterialPath(SelectedMvpCharacterProxyId));
UMaterialInterface* PackMaterial = LoadObject<UMaterialInterface>(
nullptr,
TEXT("/Game/Agrarian/Materials/M_AGR_GZ_Fiber_Resource.M_AGR_GZ_Fiber_Resource"));
UMaterialInterface* BootMaterial = LoadObject<UMaterialInterface>(
nullptr,
TEXT("/Game/Agrarian/Materials/M_AGR_GZ_Wood_Resource.M_AGR_GZ_Wood_Resource"));
const bool bFemaleProxy = SelectedMvpCharacterProxyId == TEXT("female");
const float TorsoWidth = bFemaleProxy ? 0.33f : 0.38f;
const float TorsoDepth = bFemaleProxy ? 0.18f : 0.22f;
const float PackWidth = bFemaleProxy ? 0.24f : 0.28f;
EnsureMvpPresentationComponent(
AgrarianCharacter,
TEXT("MvpWorkwearTorsoProxy"),
ChamferMesh,
WorkwearMaterial,
FVector(2.0f, 0.0f, 102.0f),
FRotator(0.0f, 0.0f, 0.0f),
FVector(TorsoWidth, TorsoDepth, 0.62f));
EnsureMvpPresentationComponent(
AgrarianCharacter,
TEXT("MvpWorkwearBackpackProxy"),
ChamferMesh,
PackMaterial,
FVector(-24.0f, 0.0f, 106.0f),
FRotator(0.0f, 0.0f, 0.0f),
FVector(PackWidth, 0.16f, 0.48f));
EnsureMvpPresentationComponent(
AgrarianCharacter,
TEXT("MvpWorkwearBedrollProxy"),
CylinderMesh,
PackMaterial,
FVector(-30.0f, 0.0f, 134.0f),
FRotator(0.0f, 90.0f, 0.0f),
FVector(0.12f, 0.12f, 0.58f));
EnsureMvpPresentationComponent(
AgrarianCharacter,
TEXT("MvpWorkwearBootsProxy"),
ChamferMesh,
BootMaterial,
FVector(0.0f, 0.0f, 26.0f),
FRotator(0.0f, 0.0f, 0.0f),
FVector(0.34f, 0.20f, 0.18f));
}
void AAgrarianGamePlayerController::AgrarianGrantItem(FName ItemId, int32 Quantity)
@@ -558,6 +811,14 @@ void AAgrarianGamePlayerController::AgrarianSelectCharacter(FName Archetype)
ClientMessage(TEXT("Usage: AgrarianSelectCharacter male|female"));
}
void AAgrarianGamePlayerController::AgrarianCompleteFrontend()
{
ApplyMvpCharacterProxyToPawn();
SetMvpFrontendPresentationActive(false);
SetInputMode(FInputModeGameOnly());
bShowMouseCursor = false;
}
void AAgrarianGamePlayerController::AgrarianShowMvpScreen(FName ScreenName)
{
if (!MvpFrontendWidget)