diff --git a/ProjectFish/Content/Gameplay/Ship/BP_Ship.uasset b/ProjectFish/Content/Gameplay/Ship/BP_Ship.uasset new file mode 100644 index 0000000..d0710bb Binary files /dev/null and b/ProjectFish/Content/Gameplay/Ship/BP_Ship.uasset differ diff --git a/ProjectFish/Content/Gameplay/Ship/BP_ShipGameMode.uasset b/ProjectFish/Content/Gameplay/Ship/BP_ShipGameMode.uasset new file mode 100644 index 0000000..c57d896 Binary files /dev/null and b/ProjectFish/Content/Gameplay/Ship/BP_ShipGameMode.uasset differ diff --git a/ProjectFish/Content/Gameplay/Ship/Cube.uasset b/ProjectFish/Content/Gameplay/Ship/Cube.uasset new file mode 100644 index 0000000..dbbb52a Binary files /dev/null and b/ProjectFish/Content/Gameplay/Ship/Cube.uasset differ diff --git a/ProjectFish/Content/Input/Actions/IA_Look.uasset b/ProjectFish/Content/Input/Actions/IA_Look.uasset new file mode 100644 index 0000000..539d3e9 Binary files /dev/null and b/ProjectFish/Content/Input/Actions/IA_Look.uasset differ diff --git a/ProjectFish/Content/Input/Actions/IA_Move.uasset b/ProjectFish/Content/Input/Actions/IA_Move.uasset new file mode 100644 index 0000000..9b52628 Binary files /dev/null and b/ProjectFish/Content/Input/Actions/IA_Move.uasset differ diff --git a/ProjectFish/Content/Input/Actions/IA_Sprint.uasset b/ProjectFish/Content/Input/Actions/IA_Sprint.uasset new file mode 100644 index 0000000..e1a52a3 Binary files /dev/null and b/ProjectFish/Content/Input/Actions/IA_Sprint.uasset differ diff --git a/ProjectFish/Content/Input/IMC_Ship.uasset b/ProjectFish/Content/Input/IMC_Ship.uasset new file mode 100644 index 0000000..b4695e6 Binary files /dev/null and b/ProjectFish/Content/Input/IMC_Ship.uasset differ diff --git a/ProjectFish/Content/Maps/Ship.umap b/ProjectFish/Content/Maps/Ship.umap new file mode 100644 index 0000000..5164651 Binary files /dev/null and b/ProjectFish/Content/Maps/Ship.umap differ diff --git a/ProjectFish/Source/ProjectFish/Definations.h b/ProjectFish/Source/ProjectFish/Definations.h index 3181401..5a7875d 100644 --- a/ProjectFish/Source/ProjectFish/Definations.h +++ b/ProjectFish/Source/ProjectFish/Definations.h @@ -207,3 +207,68 @@ public: UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ToolTip = "技能效果组")) TArray 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; +}; diff --git a/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.cpp b/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.cpp new file mode 100644 index 0000000..49bc45f --- /dev/null +++ b/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.cpp @@ -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(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(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(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(Controller)) + { + if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem(PlayerController->GetLocalPlayer())) + { + Subsystem->AddMappingContext(DefaultMappingContext, 0); + } + } +} + +// Called to bind functionality to input +void AShipbase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) +{ + Super::SetupPlayerInputComponent(PlayerInputComponent); + if (UEnhancedInputComponent* EnhancedInputComponent = Cast(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(); + + 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(); + + 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; +} + + + diff --git a/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.h b/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.h new file mode 100644 index 0000000..7ed7209 --- /dev/null +++ b/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.h @@ -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; +}; + + + + diff --git a/ProjectFish/Source/ProjectFish/ProjectFish.Build.cs b/ProjectFish/Source/ProjectFish/ProjectFish.Build.cs index fbd275c..225e8e9 100644 --- a/ProjectFish/Source/ProjectFish/ProjectFish.Build.cs +++ b/ProjectFish/Source/ProjectFish/ProjectFish.Build.cs @@ -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" }); } }