GameMode
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "MyGameModeClass.generated.h"UCLASS()
class MYDOCKINGSYSTEM_API AMyGameModeClass : public AGameModeBase
{GENERATED_BODY()
public:AMyGameModeClass();virtual void BeginPlay() override;
};
// Fill out your copyright notice in the Description page of Project Settings.#include "MyGameModeClass.h"#include "MyPawnClass.h"
#include "MyPlayerControllerClass.h"AMyGameModeClass::AMyGameModeClass()
{DefaultPawnClass = AMyPawnClass::StaticClass();PlayerControllerClass = AMyPlayerControllerClass::StaticClass();
}void AMyGameModeClass::BeginPlay()
{Super::BeginPlay();}
PlayerController
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "MyPlayerControllerClass.generated.h"/*** */
UCLASS()
class MYDOCKINGSYSTEM_API AMyPlayerControllerClass : public APlayerController
{GENERATED_BODY()public:virtual void BeginPlay() override;
};
// Fill out your copyright notice in the Description page of Project Settings.#include "MyPlayerControllerClass.h"void AMyPlayerControllerClass::BeginPlay()
{Super::BeginPlay();bShowMouseCursor = true;
}
Pawn c++中不用关闭Inherit Pitch
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
#include "InputActionValue.h"#include "MyPawnClass.generated.h"UCLASS()
class MYDOCKINGSYSTEM_API AMyPawnClass : public APawn
{GENERATED_BODY()public:// Sets default values for this pawn's propertiesAMyPawnClass();protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:// Called every framevirtual void Tick(float DeltaTime) override;// Called to bind functionality to inputvirtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;APlayerController* MyPawnController = nullptr;FVector2D MouseXY = FVector2D::ZeroVector;UPROPERTY(EditAnywhere,BlueprintReadWrite)float PawnTargetArmLength = 400.0f;UPROPERTY(EditAnywhere)USceneComponent* DefaultSceneRoot;UPROPERTY(EditAnywhere)USpringArmComponent* SpringArm;UPROPERTY(EditDefaultsOnly,BlueprintReadWrite)UInputMappingContext* mappingContext;UPROPERTY(EditDefaultsOnly,BlueprintReadWrite)FVector StartArmRotation;UPROPERTY(EditDefaultsOnly,BlueprintReadWrite)UInputAction* ActorRotation;UFUNCTION()void ContrRotation(const FInputActionValue& Value);UPROPERTY(EditDefaultsOnly,BlueprintReadWrite)UInputAction* MouseLeftClicked;UPROPERTY(EditDefaultsOnly,BlueprintReadWrite)UInputAction* MouseWheelDown;UPROPERTY(EditAnywhere,BlueprintReadWrite)float MoveSpeed = 10.0f;UPROPERTY(EditAnywhere,blueprintreadwrite)float MoveDirct = 1.0f;UPROPERTY(EditAnywhere,blueprintreadwrite)float MoveUpDirct = 1.0f;UFUNCTION()void MovePawn();UPROPERTY(EditDefaultsOnly,BlueprintReadWrite)UInputAction* ZoomLength;UPROPERTY(EditAnywhere,BlueprintReadWrite)float ZoomSpeed = 1.0f;UPROPERTY(EditAnywhere,BlueprintReadWrite)float MinLength = 100.0f;UPROPERTY(EditAnywhere,BlueprintReadWrite)float MaxLength = 800.0f;UFUNCTION()void ZoomInAndOut(const FInputActionValue& Value);
};
// Fill out your copyright notice in the Description page of Project Settings.#include "MyPawnClass.h"#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Kismet/KismetMathLibrary.h"// Sets default values
AMyPawnClass::AMyPawnClass()
{// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;DefaultSceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("DefaultSceneRoot"));RootComponent = DefaultSceneRoot;SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));SpringArm->SetupAttachment(RootComponent);SpringArm->bUsePawnControlRotation = true;SpringArm->bInheritYaw = true;SpringArm->bInheritRoll = true;SpringArm->bInheritPitch = true;SpringArm->TargetArmLength = PawnTargetArmLength;SpringArm->bDoCollisionTest = false;UCameraComponent* cameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));cameraComponent->SetupAttachment(SpringArm);//设置玩家0AutoPossessPlayer = EAutoReceiveInput::Player0;
}// Called when the game starts or when spawned
void AMyPawnClass::BeginPlay()
{Super::BeginPlay();MyPawnController = Cast<APlayerController>(GetController());if (MyPawnController){UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(MyPawnController->GetLocalPlayer());Subsystem->AddMappingContext(mappingContext,0);}
}// Called every frame
void AMyPawnClass::Tick(float DeltaTime)
{Super::Tick(DeltaTime);
}// Called to bind functionality to input
void AMyPawnClass::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{Super::SetupPlayerInputComponent(PlayerInputComponent);// 如果当前的 PlayerInputComponent 不是增强输入组件,则尝试附加UEnhancedInputComponent* LocalInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);if (!LocalInputComponent){LocalInputComponent = NewObject<UEnhancedInputComponent>(this, TEXT("EnhancedInputComponent"));if (LocalInputComponent){LocalInputComponent->RegisterComponent();PlayerInputComponent = LocalInputComponent;}else{UE_LOG(LogTemp, Error, TEXT("Failed to create EnhancedInputComponent!"));return;}}if (LocalInputComponent){LocalInputComponent->BindAction(ActorRotation,ETriggerEvent::Triggered,this,&AMyPawnClass::ContrRotation);LocalInputComponent->BindAction(MouseWheelDown,ETriggerEvent::Triggered,this,&AMyPawnClass::MovePawn);LocalInputComponent->BindAction(ZoomLength,ETriggerEvent::Triggered,this,&AMyPawnClass::ZoomInAndOut);}
}void AMyPawnClass::ContrRotation(const FInputActionValue& Value)
{MouseXY = Value.Get<FVector2D>();bool bIsMouseButtonPressed = MyPawnController->IsInputKeyDown(EKeys::LeftMouseButton);if (bIsMouseButtonPressed){AddControllerYawInput(MouseXY.X * -1.0f);SpringArm->AddLocalRotation(FRotator(MouseXY.Y));}
}void AMyPawnClass::MovePawn()
{float Deltax = 0.0f;float DeltaY = 0.0f;// 获取当前玩家控制器APlayerController* PawnPlayerController = GetWorld()->GetFirstPlayerController();if (PawnPlayerController){// 获取鼠标移动增量PawnPlayerController->GetInputMouseDelta(Deltax, DeltaY);// 设置鼠标移动的阈值,过滤微小输入const float Threshold = 0.1f;if (FMath::Abs(Deltax) < Threshold && FMath::Abs(DeltaY) < Threshold){return; // 如果增量太小,直接退出}// 获取控制器的方向向量(基于世界坐标)FRotator ControllerRotation = PawnPlayerController->GetControlRotation();FVector RightVector = FRotationMatrix(ControllerRotation).GetUnitAxis(EAxis::Y); // 右方向RightVector *= MoveDirct;// 使用固定的世界 Z 轴方向FVector UpVector(0.0f, 0.0f, 1.0f);UpVector *= MoveUpDirct;// 计算鼠标增量在世界坐标系中的偏移量FVector CurrentRightOffset = RightVector * Deltax; // 鼠标左右 → 控制器右方向FVector CurrentUpOffset = UpVector * DeltaY; // 鼠标上下 → 世界 Z 轴方向// 最终偏移量,乘以移动速度FVector FinalOffset = (CurrentRightOffset + CurrentUpOffset) * MoveSpeed;// 应用世界偏移AddActorWorldOffset(FinalOffset, true); // 使用世界偏移,启用碰撞检测}
}void AMyPawnClass::ZoomInAndOut(const FInputActionValue& Value)
{float PawnSpringArmLength = Value.Get<float>();float CurrentLength = SpringArm->TargetArmLength + PawnSpringArmLength * ZoomSpeed;SpringArm->TargetArmLength = FMath::Clamp(CurrentLength,MinLength,MaxLength);
}
完美平移,关闭Inherit Pitch
Pawn SpringArmLength 距离控制速度(创建Curve Float引用,添加自定义曲线)