Make top-down the default camera mode and bind camera toggle to C.
Matches Fantasy Life style gameplay; first-person remains available as an optional mode. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
0ced5b17ef
commit
c0d9450d30
@ -4,7 +4,7 @@ A life-simulation action RPG remake inspired by Fantasy Life, built in **Unreal
|
|||||||
|
|
||||||
## Vision
|
## Vision
|
||||||
|
|
||||||
- First-person gameplay (primary) with classic top-down camera toggle
|
- First-person gameplay with classic top-down camera as the default (toggle with C)
|
||||||
- Mouse, keyboard, and gamepad support via Enhanced Input
|
- Mouse, keyboard, and gamepad support via Enhanced Input
|
||||||
- Co-op multiplayer (listen server first, dedicated server hosting)
|
- Co-op multiplayer (listen server first, dedicated server hosting)
|
||||||
- Optional hardware ray tracing and scalability presets
|
- Optional hardware ray tracing and scalability presets
|
||||||
@ -31,7 +31,7 @@ A life-simulation action RPG remake inspired by Fantasy Life, built in **Unreal
|
|||||||
| Jump | Space | A / Cross |
|
| Jump | Space | A / Cross |
|
||||||
| Interact / Craft | E | X / Square |
|
| Interact / Craft | E | X / Square |
|
||||||
| Attack | LMB | RT |
|
| Attack | LMB | RT |
|
||||||
| Toggle camera (FP / Top-Down) | V | Menu |
|
| Toggle camera (Top-Down / FP) | C | Menu |
|
||||||
| Quick save | I | Y / Triangle |
|
| Quick save | I | Y / Triangle |
|
||||||
| Pause | Esc | Start |
|
| Pause | Esc | Start |
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,7 @@ AVocationCharacter::AVocationCharacter()
|
|||||||
FirstPersonCamera->SetupAttachment(GetCapsuleComponent());
|
FirstPersonCamera->SetupAttachment(GetCapsuleComponent());
|
||||||
FirstPersonCamera->SetRelativeLocation(FVector(0.f, 0.f, 64.f));
|
FirstPersonCamera->SetRelativeLocation(FVector(0.f, 0.f, 64.f));
|
||||||
FirstPersonCamera->bUsePawnControlRotation = true;
|
FirstPersonCamera->bUsePawnControlRotation = true;
|
||||||
|
FirstPersonCamera->SetActive(false);
|
||||||
|
|
||||||
TopDownSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("TopDownSpringArm"));
|
TopDownSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("TopDownSpringArm"));
|
||||||
TopDownSpringArm->SetupAttachment(RootComponent);
|
TopDownSpringArm->SetupAttachment(RootComponent);
|
||||||
@ -42,7 +43,7 @@ AVocationCharacter::AVocationCharacter()
|
|||||||
TopDownSpringArm->bInheritPitch = false;
|
TopDownSpringArm->bInheritPitch = false;
|
||||||
TopDownSpringArm->bInheritRoll = false;
|
TopDownSpringArm->bInheritRoll = false;
|
||||||
TopDownSpringArm->bInheritYaw = false;
|
TopDownSpringArm->bInheritYaw = false;
|
||||||
TopDownSpringArm->SetActive(false);
|
TopDownSpringArm->SetActive(true);
|
||||||
|
|
||||||
TopDownCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("TopDownCamera"));
|
TopDownCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("TopDownCamera"));
|
||||||
TopDownCamera->SetupAttachment(TopDownSpringArm, USpringArmComponent::SocketName);
|
TopDownCamera->SetupAttachment(TopDownSpringArm, USpringArmComponent::SocketName);
|
||||||
@ -54,21 +55,25 @@ AVocationCharacter::AVocationCharacter()
|
|||||||
|
|
||||||
if (USkeletalMeshComponent* MeshComp = GetMesh())
|
if (USkeletalMeshComponent* MeshComp = GetMesh())
|
||||||
{
|
{
|
||||||
MeshComp->SetOnlyOwnerSee(true);
|
// Visible body for top-down default; FP mode reattaches in ApplyCameraModeVisuals.
|
||||||
MeshComp->SetupAttachment(FirstPersonCamera);
|
MeshComp->SetOnlyOwnerSee(false);
|
||||||
MeshComp->SetRelativeLocation(FVector(25.f, 0.f, -90.f));
|
MeshComp->SetOwnerNoSee(false);
|
||||||
|
MeshComp->SetupAttachment(GetCapsuleComponent());
|
||||||
|
MeshComp->SetRelativeLocation(FVector(0.f, 0.f, -90.f));
|
||||||
|
MeshComp->SetRelativeRotation(FRotator(0.f, -90.f, 0.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UCharacterMovementComponent* Movement = GetCharacterMovement())
|
if (UCharacterMovementComponent* Movement = GetCharacterMovement())
|
||||||
{
|
{
|
||||||
Movement->bOrientRotationToMovement = false;
|
Movement->bOrientRotationToMovement = true;
|
||||||
Movement->RotationRate = FRotator(0.f, 540.f, 0.f);
|
Movement->RotationRate = FRotator(0.f, 540.f, 0.f);
|
||||||
Movement->JumpZVelocity = 500.f;
|
Movement->JumpZVelocity = 500.f;
|
||||||
Movement->AirControl = 0.35f;
|
Movement->AirControl = 0.35f;
|
||||||
Movement->MaxWalkSpeed = 500.f;
|
Movement->MaxWalkSpeed = 500.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bUseControllerRotationPitch = true;
|
// Top-down is the default camera mode (Fantasy Life style).
|
||||||
|
bUseControllerRotationPitch = false;
|
||||||
bUseControllerRotationYaw = true;
|
bUseControllerRotationYaw = true;
|
||||||
bUseControllerRotationRoll = false;
|
bUseControllerRotationRoll = false;
|
||||||
}
|
}
|
||||||
@ -304,6 +309,25 @@ void AVocationCharacter::ApplyCameraModeVisuals()
|
|||||||
TopDownSpringArm->SetActive(!bFirstPerson);
|
TopDownSpringArm->SetActive(!bFirstPerson);
|
||||||
TopDownCamera->SetActive(!bFirstPerson);
|
TopDownCamera->SetActive(!bFirstPerson);
|
||||||
|
|
||||||
|
if (USkeletalMeshComponent* MeshComp = GetMesh())
|
||||||
|
{
|
||||||
|
if (bFirstPerson)
|
||||||
|
{
|
||||||
|
MeshComp->SetOnlyOwnerSee(true);
|
||||||
|
MeshComp->SetupAttachment(FirstPersonCamera);
|
||||||
|
MeshComp->SetRelativeLocation(FVector(25.f, 0.f, -90.f));
|
||||||
|
MeshComp->SetRelativeRotation(FRotator::ZeroRotator);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MeshComp->SetOnlyOwnerSee(false);
|
||||||
|
MeshComp->SetOwnerNoSee(false);
|
||||||
|
MeshComp->SetupAttachment(GetCapsuleComponent());
|
||||||
|
MeshComp->SetRelativeLocation(FVector(0.f, 0.f, -90.f));
|
||||||
|
MeshComp->SetRelativeRotation(FRotator(0.f, -90.f, 0.f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bUseControllerRotationPitch = bFirstPerson;
|
bUseControllerRotationPitch = bFirstPerson;
|
||||||
if (UCharacterMovementComponent* Movement = GetCharacterMovement())
|
if (UCharacterMovementComponent* Movement = GetCharacterMovement())
|
||||||
{
|
{
|
||||||
|
|||||||
@ -76,7 +76,7 @@ void AVocationHUD::DrawMainHUD()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const FString Controls = TEXT("WASD Move | Mouse Look | V Camera | E Interact/Craft | LMB Attack | I Save | Esc Pause");
|
const FString Controls = TEXT("WASD Move | Mouse Look | C Camera | E Interact/Craft | LMB Attack | I Save | Esc Pause");
|
||||||
Canvas->DrawColor = FColor(200, 200, 200);
|
Canvas->DrawColor = FColor(200, 200, 200);
|
||||||
Canvas->DrawText(GEngine->GetSmallFont(), Controls, 40.f * Scale, Canvas->ClipY - 60.f * Scale, Scale, Scale);
|
Canvas->DrawText(GEngine->GetSmallFont(), Controls, 40.f * Scale, Canvas->ClipY - 60.f * Scale, Scale, Scale);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ void AVocationPlayerController::BeginPlay()
|
|||||||
LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
|
LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
|
||||||
{
|
{
|
||||||
Subsystem->AddMappingContext(SharedMappingContext, SharedMappingPriority);
|
Subsystem->AddMappingContext(SharedMappingContext, SharedMappingPriority);
|
||||||
Subsystem->AddMappingContext(FirstPersonMappingContext, ModeMappingPriority);
|
Subsystem->AddMappingContext(TopDownMappingContext, ModeMappingPriority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ void AVocationPlayerController::CreateRuntimeInputAssets()
|
|||||||
SharedMappingContext->MapKey(JumpAction, EKeys::SpaceBar);
|
SharedMappingContext->MapKey(JumpAction, EKeys::SpaceBar);
|
||||||
SharedMappingContext->MapKey(InteractAction, EKeys::E);
|
SharedMappingContext->MapKey(InteractAction, EKeys::E);
|
||||||
SharedMappingContext->MapKey(AttackAction, EKeys::LeftMouseButton);
|
SharedMappingContext->MapKey(AttackAction, EKeys::LeftMouseButton);
|
||||||
SharedMappingContext->MapKey(ToggleCameraAction, EKeys::V);
|
SharedMappingContext->MapKey(ToggleCameraAction, EKeys::C);
|
||||||
SharedMappingContext->MapKey(InventoryAction, EKeys::I);
|
SharedMappingContext->MapKey(InventoryAction, EKeys::I);
|
||||||
SharedMappingContext->MapKey(PauseAction, EKeys::Escape);
|
SharedMappingContext->MapKey(PauseAction, EKeys::Escape);
|
||||||
SharedMappingContext->MapKey(JumpAction, EKeys::Gamepad_FaceButton_Bottom);
|
SharedMappingContext->MapKey(JumpAction, EKeys::Gamepad_FaceButton_Bottom);
|
||||||
|
|||||||
@ -110,10 +110,10 @@ protected:
|
|||||||
void UpdateInteractionPrompt();
|
void UpdateInteractionPrompt();
|
||||||
|
|
||||||
UPROPERTY(ReplicatedUsing = OnRep_CameraMode, BlueprintReadOnly, Category = "VocationLife|Camera")
|
UPROPERTY(ReplicatedUsing = OnRep_CameraMode, BlueprintReadOnly, Category = "VocationLife|Camera")
|
||||||
EVocationCameraMode CurrentCameraMode = EVocationCameraMode::FirstPerson;
|
EVocationCameraMode CurrentCameraMode = EVocationCameraMode::TopDown;
|
||||||
|
|
||||||
UPROPERTY(ReplicatedUsing = OnRep_CameraMode)
|
UPROPERTY(ReplicatedUsing = OnRep_CameraMode)
|
||||||
EVocationCameraMode TargetCameraMode = EVocationCameraMode::FirstPerson;
|
EVocationCameraMode TargetCameraMode = EVocationCameraMode::TopDown;
|
||||||
|
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
float CameraBlendAlpha = 1.f;
|
float CameraBlendAlpha = 1.f;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user