UE5.2.1 C++ 俯视角模板

GameMode.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "TDJGameMode.generated.h"

UCLASS(minimalapi)
class ATDJGameMode : public AGameModeBase
{
	GENERATED_BODY()

public:
	ATDJGameMode();
};

 GameMode.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "TDJGameMode.h"
#include "TDJPlayerController.h"
#include "TDJCharacter.h"
#include "UObject/ConstructorHelpers.h"

ATDJGameMode::ATDJGameMode()
{
	// 使用我们自定义的PlayerController类
	PlayerControllerClass = ATDJPlayerController::StaticClass();
	// 设置默认Pawn为我们的蓝图角色
	static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownCharacter"));
	if (PlayerPawnBPClass.Class != nullptr)
	{
		DefaultPawnClass = PlayerPawnBPClass.Class;
	}
	// 设置默认控制器为我们的蓝图控制器
	static ConstructorHelpers::FClassFinder<APlayerController> PlayerControllerBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownPlayerController"));
	if(PlayerControllerBPClass.Class != NULL)
	{
		PlayerControllerClass = PlayerControllerBPClass.Class;
	}
}

Character.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "TDJCharacter.generated.h"

UCLASS(Blueprintable)
class ATDJCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	ATDJCharacter();

	// Called every frame.
	virtual void Tick(float DeltaSeconds) override;

	/** 返回摄像机组件的子对象 **/
	FORCEINLINE class UCameraComponent* GetTopDownCameraComponent() const { return TopDownCameraComponent; }
	/** 返回弹簧臂组件的子对象 **/
	FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }

private:
	/** 摄像机组件声明 */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
	class UCameraComponent* TopDownCameraComponent;

	/** 弹簧臂组件声明 */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
	class USpringArmComponent* CameraBoom;
};

Character.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "TDJCharacter.h"
#include "UObject/ConstructorHelpers.h"
#include "Camera/CameraComponent.h"//摄像机组件
#include "Components/DecalComponent.h"//贴花组件
#include "Components/CapsuleComponent.h"//胶囊体组件
#include "GameFramework/CharacterMovementComponent.h"//角色移动组件
#include "GameFramework/PlayerController.h"//玩家控制器组件
#include "GameFramework/SpringArmComponent.h"//弹簧臂组件
#include "Materials/Material.h"
#include "Engine/World.h"

ATDJCharacter::ATDJCharacter()
{
	// 设置胶囊体形状(半径:42.0,半高:96.0)
	GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);

	// 摄像机视角不影响角色视角
	bUseControllerRotationPitch = false;
	bUseControllerRotationYaw = false;
	bUseControllerRotationRoll = false;

	// 配置角色移动
	GetCharacterMovement()->bOrientRotationToMovement = true; // 将旋转朝向运动设置为true
	GetCharacterMovement()->RotationRate = FRotator(0.f, 640.f, 0.f);//设置旋转速率
	GetCharacterMovement()->bConstrainToPlane = true;//约束到平面
	GetCharacterMovement()->bSnapToPlaneAtStart = true;//开始时与平面对齐

	// 初始化弹簧臂...
	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(RootComponent);
	CameraBoom->SetUsingAbsoluteRotation(true); // Don't want arm to rotate when character does
	CameraBoom->TargetArmLength = 1400.f;//目标臂长度
	CameraBoom->SetRelativeRotation(FRotator(-60.f, 0.f, 0.f));//相对旋转
	CameraBoom->bDoCollisionTest = false; // 进行碰撞测试设置为false

	// 初始化摄像机...
	TopDownCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("TopDownCamera"));
	TopDownCameraComponent->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
	TopDownCameraComponent->bUsePawnControlRotation = false; // 使用Pawn控制旋转设置为false

	// 激活Tick,以便每帧更新光标。
	PrimaryActorTick.bCanEverTick = true;
	PrimaryActorTick.bStartWithTickEnabled = true;
}

void ATDJCharacter::Tick(float DeltaSeconds)
{
    Super::Tick(DeltaSeconds);
}

 PlayerController.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "Templates/SubclassOf.h"//模板子类组件
#include "GameFramework/PlayerController.h"//玩家控制器组件
#include "InputActionValue.h"
#include "TDJPlayerController.generated.h"

/** 创建粒子系统 */
class UNiagaraSystem;

UCLASS()
class ATDJPlayerController : public APlayerController
{
	GENERATED_BODY()

public:
	ATDJPlayerController();

	/** Time Threshold to know if it was a short press */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
	float ShortPressThreshold;

	/** Niagara系统声明 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
	UNiagaraSystem* FXCursor;

	/** 输入映射上下文声明 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
	class UInputMappingContext* DefaultMappingContext;
	
	/** 跳跃输入操作 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
	class UInputAction* SetDestinationClickAction;

	/** 跳跃输入操作(触摸) */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
	class UInputAction* SetDestinationTouchAction;

protected:
	/** 移动到鼠标位置,返回True. */
	uint32 bMoveToMouseCursor : 1;

	virtual void SetupInputComponent() override;
	
	// 添加映射上下文
	virtual void BeginPlay();

	void OnInputStarted();
	void OnSetDestinationTriggered();
	void OnSetDestinationReleased();
	void OnTouchTriggered();
	void OnTouchReleased();

private:
	FVector CachedDestination;

	bool bIsTouch; //是否为触摸设备
	float FollowTime; // 按压时间
};


 PlayerController.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "TDJPlayerController.h"
#include "GameFramework/Pawn.h"//Pawn组件
#include "Blueprint/AIBlueprintHelperLibrary.h"//AI蓝图助手库
#include "NiagaraSystem.h"//Niagara系统组件
#include "NiagaraFunctionLibrary.h"//Niagara函数库
#include "TDJCharacter.h"
#include "Engine/World.h"
#include "EnhancedInputComponent.h"//增强输入组件
#include "EnhancedInputSubsystems.h"//增强输入子系统组件

ATDJPlayerController::ATDJPlayerController()
{
	bShowMouseCursor = true;
	DefaultMouseCursor = EMouseCursor::Default;
	CachedDestination = FVector::ZeroVector;
	FollowTime = 0.f;
}

void ATDJPlayerController::BeginPlay()
{
	// 调用基类
	Super::BeginPlay();

	//添加输入映射上下文
	if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
	{
		Subsystem->AddMappingContext(DefaultMappingContext, 0);
	}
}

void ATDJPlayerController::SetupInputComponent()
{
	// 设置游戏按键绑定
	Super::SetupInputComponent();

	// 设置操作绑定
	if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(InputComponent))
	{
		// 设置鼠标输入事件
		EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Started, this, &ATDJPlayerController::OnInputStarted);
		EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Triggered, this, &ATDJPlayerController::OnSetDestinationTriggered);
		EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Completed, this, &ATDJPlayerController::OnSetDestinationReleased);
		EnhancedInputComponent->BindAction(SetDestinationClickAction, ETriggerEvent::Canceled, this, &ATDJPlayerController::OnSetDestinationReleased);

		// 设置触摸输入事件
		EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Started, this, &ATDJPlayerController::OnInputStarted);
		EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Triggered, this, &ATDJPlayerController::OnTouchTriggered);
		EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Completed, this, &ATDJPlayerController::OnTouchReleased);
		EnhancedInputComponent->BindAction(SetDestinationTouchAction, ETriggerEvent::Canceled, this, &ATDJPlayerController::OnTouchReleased);
	}
}

void ATDJPlayerController::OnInputStarted()
{
	StopMovement();
}

// 按下输入时每帧触发
void ATDJPlayerController::OnSetDestinationTriggered()
{
	// 输入正在被按下
	FollowTime += GetWorld()->GetDeltaSeconds();
	
	// 角色要前往的目标位置
	FHitResult Hit;
	bool bHitSuccessful = false;
	if (bIsTouch)
	{
		bHitSuccessful = GetHitResultUnderFinger(ETouchIndex::Touch1, ECollisionChannel::ECC_Visibility, true, Hit);
	}
	else
	{
		bHitSuccessful = GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility, true, Hit);
	}

	// If we hit a surface, cache the location
	if (bHitSuccessful)
	{
		CachedDestination = Hit.Location;
	}
	
	// 移动到鼠标指针或触摸
	APawn* ControlledPawn = GetPawn();
	if (ControlledPawn != nullptr)
	{
		FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();
		ControlledPawn->AddMovementInput(WorldDirection, 1.0, false);
	}
}

void ATDJPlayerController::OnSetDestinationReleased()
{
	// 如果是短按
	if (FollowTime <= ShortPressThreshold)
	{
		// 角色移动到目标位置,目标位置生成粒子
		UAIBlueprintHelperLibrary::SimpleMoveToLocation(this, CachedDestination);
		UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, FXCursor, CachedDestination, FRotator::ZeroRotator, FVector(1.f, 1.f, 1.f), true, true, ENCPoolMethod::None, true);
	}

	FollowTime = 0.f;
}

// 按下输入时每帧触发
void ATDJPlayerController::OnTouchTriggered()
{
	bIsTouch = true;
	OnSetDestinationTriggered();
}

void ATDJPlayerController::OnTouchReleased()
{
	bIsTouch = false;
	OnSetDestinationReleased();
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Woody_Dark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值