添加船角色

This commit is contained in:
997146918 2025-07-25 16:32:38 +08:00
parent d8623fb375
commit 76a8f2be4a
12 changed files with 361 additions and 1 deletions

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.

View File

@ -207,3 +207,68 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ToolTip = "技能效果组"))
TArray<FFishingRodSkill> Skills;
};
USTRUCT(BlueprintType)
struct FShipDataConfig
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ship", meta = (ForceUnits = "cm", ToolTip = "船体长度"))
int32 ShipLength = 100;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ship", meta = (ForceUnits = "cm", ToolTip = "船体宽度"))
int32 ShipWidth = 100;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ship", meta = (ForceUnits = "cm", ToolTip = "船体高度"))
int32 ShipHeight = 100;
/*** Movement ***/
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ForceUnits = "cm/s", Category = "Character|Movement", ToolTip = "正常速度"))
float BaseSpeed = 600.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Character|Movement", meta = (ForceUnits = "cm/s",ToolTip = "冲刺速度"))
float SprintSpeed = 1200.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Character|Movement", meta = (ForceUnits = "s", ToolTip = "加速到最大速度时间"))
float AccelerationTime = 0.3f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Character|Movement", meta = (ForceUnits = "s", ToolTip = "停止需要的减速时间"))
float DecelerationTime = 0.2f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Character|Movement", meta = (ToolTip = "转向灵敏度/阻尼"))
float TurnSensitivity = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Character|Movement", meta = (ToolTip = "回弹系数"))
float BounceFactor= 1.0f;
/*** Camera ***/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Position", meta = (ForceUnits = "cm", ToolTip = "与角色距离"))
float CameraDistance = 800.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Position", meta = (ForceUnits = "cm", ToolTip = "与角色高度差"))
float CameraHeightOffset = 600.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Position", meta = (ForceUnits = "Degrees",ToolTip = "镜头与地面夹角角度"))
float CameraGroundAngle = -45.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Rotation", meta = (ToolTip = "镜头转动灵命度"))
float CameraRotationSensitivity = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Rotation", meta = (ToolTip = "反转Y轴"))
bool FlipCameraYAxius = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Rotation", meta = (ForceUnits = "Degrees",ToolTip = "最大上仰角度"))
float MaxUpwardAngle = -20.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Rotation", meta = (ForceUnits = "Degrees", ToolTip = "最低下俯角度"))
float MaxDownwardAngle = -70.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Follow", meta = (ToolTip = "镜头跟随阻尼"))
float CameraFollowLagRatio = 3.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Collision", meta = (ToolTip = "镜头跟随阻尼"))
float CameraCollisionLagRatio = 3.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Collision", meta = (ForceUnits = "cm", ToolTip = "与角色的最小距离"))
float CameraMinDistance = 200.0f;
};

View File

@ -0,0 +1,206 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Shipbase.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "AI/NavigationModifier.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/SpringArmComponent.h"
class UEnhancedInputLocalPlayerSubsystem;
// Sets default values
AShipbase::AShipbase()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
GetCapsuleComponent()->SetCapsuleSize(100.f, 50.f);
//不受controller 旋转影响
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
//默认movement
GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...
GetCharacterMovement()->bUseSeparateBrakingFriction = true;
GetCharacterMovement()->RotationRate = FRotator(0.0f, 500.0f, 0.0f); // ...at this rotation rate
GetCharacterMovement()->MaxWalkSpeed = 500.f;
GetCharacterMovement()->MinAnalogWalkSpeed = 20.f;
GetCharacterMovement()->BrakingDecelerationWalking = 2000.f;
//Ship Mesh
ShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ShipMesh"));
ShipMesh->SetCollisionProfileName("OverlapAll");
//ShipMesh->GetBodyInstance()->bNotifyRigidBodyCollision = true;
ShipMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
ShipMesh->OnComponentBeginOverlap.AddDynamic(this, &AShipbase::OnOverlapWall);
ShipMesh->SetupAttachment(RootComponent);
//camera arm
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 400.0f; // The camera follows at this distance behind the character
CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller
//camera
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
FollowCamera->bUsePawnControlRotation = false;
ApplyShipSize();
ApplyMovementSettings();
ApplyCameraSettings();
}
// Called when the game starts or when spawned
void AShipbase::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AShipbase::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AShipbase::NotifyControllerChanged()
{
Super::NotifyControllerChanged();
// Add Input Mapping Context
if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
}
// Called to bind functionality to input
void AShipbase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent)) {
// Sprint
EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Started, this, &AShipbase::SprintMove);
EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Completed, this, &AShipbase::StopSprintMove);
// Moving
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AShipbase::Move);
// Looking
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AShipbase::Look);
}
else
{
UE_LOG(LogTemp, Error, TEXT("'%s' Failed to find an Enhanced Input component! This template is built to use the Enhanced Input system. If you intend to use the legacy system, then you will need to update this C++ file."), *GetNameSafe(this));
}
}
void AShipbase::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
ApplyShipSize();
ApplyMovementSettings();
ApplyCameraSettings();
}
void AShipbase::OnOverlapWall(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (OtherActor->ActorHasTag(TEXT("Wall")))
{
LaunchCharacter(GetCharacterMovement()->GetLastUpdateVelocity()*-1.f*ShipData.BounceFactor,
true, true);
}
}
void AShipbase::Move(const FInputActionValue& Value)
{
// input is a Vector2D
FVector2D MovementVector = Value.Get<FVector2D>();
if (Controller != nullptr)
{
// find out which way is forward
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// get forward vector
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
// get right vector
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
// add movement
AddMovementInput(ForwardDirection, MovementVector.Y);
AddMovementInput(RightDirection, MovementVector.X);
}
}
void AShipbase::Look(const FInputActionValue& Value)
{
// input is a Vector2D
FVector2D LookAxisVector = Value.Get<FVector2D>();
if (Controller != nullptr)
{
// add yaw and pitch input to controller
//AddControllerYawInput(LookAxisVector.X);
int32 flip = ShipData.FlipCameraYAxius ? -1 : 1;
float NewPitch = Controller->GetControlRotation().Pitch +LookAxisVector.Y*ShipData.CameraRotationSensitivity*flip;
NewPitch = FMath::Clamp(NewPitch, ShipData.MaxDownwardAngle - (ShipData.CameraGroundAngle),
ShipData.MaxUpwardAngle - (ShipData.CameraGroundAngle)); // 限制角度范围
Controller->SetControlRotation(FRotator(NewPitch, Controller->GetControlRotation().Yaw, Controller->GetControlRotation().Roll));
}
}
void AShipbase::SprintMove()
{
GetCharacterMovement()->MaxWalkSpeed = ShipData.SprintSpeed;
}
void AShipbase::StopSprintMove()
{
GetCharacterMovement()->MaxWalkSpeed = ShipData.BaseSpeed;
}
void AShipbase::ApplyShipSize()
{
GetCapsuleComponent()->SetCapsuleSize(FMath::Min(ShipData.ShipHeight/2.f, 100.f), ShipData.ShipHeight/2.f);
ShipMesh->SetWorldScale3D(FVector(ShipData.ShipLength/100.f, ShipData.ShipWidth/100.f, ShipData.ShipHeight/100.f));
}
void AShipbase::ApplyMovementSettings()
{
GetCharacterMovement()->MaxWalkSpeed = ShipData.BaseSpeed; //移动速度
GetCharacterMovement()->MaxAcceleration = ShipData.BaseSpeed/ShipData.AccelerationTime; //加速度
GetCharacterMovement()->BrakingDecelerationWalking = ShipData.BaseSpeed/ShipData.DecelerationTime; //加速度
//转动速度
FRotator NewRotationRate = GetCharacterMovement()->RotationRate;
NewRotationRate.Yaw = NewRotationRate.Yaw*ShipData.TurnSensitivity;
GetCharacterMovement()->RotationRate = NewRotationRate;
}
void AShipbase::ApplyCameraSettings()
{
CameraBoom->TargetArmLength = ShipData.CameraDistance;
CameraBoom->SocketOffset = FVector(0, 0, ShipData.CameraHeightOffset);
FollowCamera->SetRelativeRotation(FRotator(ShipData.CameraGroundAngle, 0, 0));
CameraBoom->bEnableCameraLag = true;
CameraBoom->CameraLagSpeed = ShipData.CameraFollowLagRatio;
//CameraBoom->CameraLagMaxDistance = MaxSpringDistance;
}

View File

@ -0,0 +1,88 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "InputActionValue.h"
#include "GameFramework/Character.h"
#include "ProjectFish/Definations.h"
#include "Shipbase.generated.h"
UCLASS(PrioritizeCategories = Config)
class PROJECTFISH_API AShipbase : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AShipbase();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
virtual void NotifyControllerChanged() override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
UFUNCTION()
void OnOverlapWall(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
protected:
/** Called for movement input */
void Move(const FInputActionValue& Value);
/** Called for looking input */
void Look(const FInputActionValue& Value);
void SprintMove();
void StopSprintMove();
/*** ApplyConfig ***/
void ApplyShipSize();
void ApplyMovementSettings();
void ApplyCameraSettings();
protected:
UPROPERTY(EditAnywhere,BlueprintReadOnly, Category= "Config", meta = (AllowPrivateAccess = "true"))
FShipDataConfig ShipData;
UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = Ship, meta = ( AllowPrivateAccess = "true"))
class UStaticMeshComponent* ShipMesh;
/***Camera***/
UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = Camera, meta = ( AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;
UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = Camera, meta = ( AllowPrivateAccess = "true"))
class UCameraComponent* FollowCamera;
/***Input***/
/** MappingContext */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputMappingContext* DefaultMappingContext;
/** Sprint Move Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* SprintAction;
/** Move Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* MoveAction;
/** Look Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* LookAction;
};

View File

@ -8,6 +8,7 @@ public class ProjectFish : ModuleRules
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
OptimizeCode = CodeOptimization.Never;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "NavigationSystem", "AIModule", "Niagara", "EnhancedInput", "GameplayTags" });
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine",
"InputCore", "NavigationSystem", "AIModule", "Niagara", "EnhancedInput", "GameplayTags" });
}
}