虚幻引擎5 GAS开发俯视角RPG游戏 P07-06 能力输入的回调

1.调整一下输入资产,将输入映射上下文添加进去:

2.新增自定义输入组件,创建函数BindAbilityAction:

Source/CC_Aura/Public/Input/CC_InputComponent.h

cpp 复制代码
// 版权归陈超所有

#pragma once

#include "CoreMinimal.h"
#include "DataAsset_InputConfig.h"
#include "EnhancedInputComponent.h"
#include "CC_InputComponent.generated.h"

class UDataAsset_InputConfig;
/**
 * 
 */
UCLASS()
class CC_AURA_API UCC_InputComponent : public UEnhancedInputComponent
{
	GENERATED_BODY()
public:
	template<class UserObject, typename CallbackFunc>
	void BindAbilityAction(const UDataAsset_InputConfig* InInputConfig, const FGameplayTag& InInputTag, ETriggerEvent TriggerEvent ,UserObject* ContextObject, CallbackFunc Func);
};

template <class UserObject, typename CallbackFunc>
void UCC_InputComponent::BindAbilityAction(const UDataAsset_InputConfig* InInputConfig, const FGameplayTag& InInputTag,
	ETriggerEvent TriggerEvent, UserObject* ContextObject, CallbackFunc Func)
{
	checkf(InInputConfig, TEXT("[%s]里的InInputConfig为空指针,无法继续执行绑定操作!"),*GetName());
	UInputAction* InputAction = InInputConfig->GetInputActionByTag(InInputTag);
	if (InputAction == nullptr) return;
	BindAction(InputAction, TriggerEvent, ContextObject, Func);
}

在编辑器项目设置里,将"默认输入组件类"改成自己的输入组件类:

3.在CC_PlayerController.h中添加输入数据资产,顺便把其他的输入映射上下文和输入动作删除:

cpp 复制代码
// 版权归陈超所有

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "CC_PlayerController.generated.h"

class UDataAsset_InputConfig;
class ICC_EnemyInterface;
class UInputMappingContext;
class UInputAction;


/**
 * 
 */
UCLASS()
class CC_AURA_API ACC_PlayerController : public APlayerController
{
	GENERATED_BODY()

public:
	ACC_PlayerController();
	virtual void PlayerTick(float DeltaTime) override;
protected:
	virtual void BeginPlay() override;

#pragma region CurserTrace
private:
	//鼠标追踪变量
	TScriptInterface<ICC_EnemyInterface> LastActor;	//上一帧拾取的接口指针
	TScriptInterface<ICC_EnemyInterface> ThisActor;	//当前帧拾取的接口指针

	void CurserTrace();	//鼠标追踪函数
#pragma endregion
	
#pragma region Inputs
protected:
	virtual void SetupInputComponent() override;
private:
	UPROPERTY(EditAnywhere, Category="CC|Input")
	TObjectPtr<UDataAsset_InputConfig> DataAssetInputConfig;
	
	void Move(const struct FInputActionValue& InputActionValue);
#pragma endregion
	
};

Source/CC_Aura/Private/Player/CC_PlayerController.cpp

源码:

cpp 复制代码
// 版权归陈超所有


#include "Player/CC_PlayerController.h"

#include "CC_GameplayTags.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
#include "Input/CC_InputComponent.h"
#include "Interations/CC_EnemyInterface.h"

ACC_PlayerController::ACC_PlayerController()
{
	bReplicates = true;		//确保可复制
}

void ACC_PlayerController::PlayerTick(float DeltaTime)
{
	Super::PlayerTick(DeltaTime);
	CurserTrace();

}


//鼠标位置追踪
void ACC_PlayerController::CurserTrace()
{
	FHitResult CursorHit;
	GetHitResultUnderCursor(ECC_Visibility, false, CursorHit);	//获取可视的鼠标命中结果
	if(!CursorHit.bBlockingHit) return; //如果未命中直接返回

	LastActor = ThisActor;
	ThisActor = CursorHit.GetActor();
	/**
	 * 射线拾取后,会出现的几种情况
	 * 1. LastActor is null   ThisActor is null 不需要任何操作
	 * 2. LastActor is null   ThisActor is valid 高亮ThisActor
	 * 3. LastActor is valid   ThisActor is null 取消高亮LastActor
	 * 4. LastActor is valid   ThisActor is valid LastActor != ThisActor 取消高亮LastActor 高亮ThisActor
	 * 5. LastActor is valid   ThisActor is valid LastActor == ThisActor 不需要任何操作
	 */
	
	if(LastActor == nullptr)
	{
		if(ThisActor != nullptr)
		{
			//case 2
			ThisActor->HighlightActor();
		} // else case 1
	}
	else
	{
		if(ThisActor == nullptr)
		{
			//case 3
			LastActor->UnHighlightActor();
		}
		else
		{
			if(LastActor != ThisActor)
			{
				//case 4
				LastActor->UnHighlightActor();
				ThisActor->HighlightActor();
			} //else case 5
		}
	}	
}


void ACC_PlayerController::BeginPlay()
{
	Super::BeginPlay();

	/*
	check(CCContext);//判断增强输入映射情境是否存在
	
	//从本地角色身上获取到它的子系统
	UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
	// check(Subsystem);//检查子系统是否存在
	if (Subsystem)
	{
		Subsystem->AddMappingContext(CCContext,0);//子系统配置情境
	}
	*/
		
	//设置鼠标光标
	bShowMouseCursor = true; //游戏中是否显示鼠标光标
	DefaultMouseCursor = EMouseCursor::Default; //鼠标光标的样式

	FInputModeGameAndUI InputModeData;
	InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock); //将鼠标锁定在视口内
	InputModeData.SetHideCursorDuringCapture(false); //鼠标被捕获时是否隐藏
	SetInputMode(InputModeData); //设置给控制器

}

//设置输入组件函数(重载)
void ACC_PlayerController::SetupInputComponent()
{
	Super::SetupInputComponent();

	checkf(DataAssetInputConfig,TEXT("DataAssetInputConfig 指针为空!"));
	
	UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
	if(Subsystem == nullptr) return;
	//添加映射上下文
	Subsystem->AddMappingContext(DataAssetInputConfig->DefaultMappingContext, 0);

	
	UCC_InputComponent* CC_InputComponent = CastChecked<UCC_InputComponent>(InputComponent); //将InputComponent转换成增强输入组件

	CC_InputComponent->BindAbilityAction(DataAssetInputConfig, CC_GameplayTags::Input_Move, ETriggerEvent::Triggered, this, &ThisClass::Move); //绑定移动事件
}

//移动事件的返回函数
void ACC_PlayerController::Move(const struct FInputActionValue& InputActionValue)
{
	const FVector2D InputAxisVector = InputActionValue.Get<FVector2D>(); //获取输入操作的2维向量值
	const FRotator Rotation = GetControlRotation(); //获取控制器旋转
	const FRotator YawRotation(0.f, Rotation.Yaw, 0.f); //通过控制器的垂直朝向创建一个旋转值,忽略上下朝向和左右朝向

	const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); //获取向前的值(旋转矩阵)
	const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); //获取向右的值,-1到1

	if(APawn* ControlledPawn = GetPawn<APawn>())
	{
		ControlledPawn->AddMovementInput(ForwardDirection, InputAxisVector.Y);
		ControlledPawn->AddMovementInput(RightDirection, InputAxisVector.X);
	}
	
}

在编辑器玩家控制器类中,添加输入配置资产:

相关推荐
煤球王子3 小时前
学而时习之:C++中的字符串
c++
go_bai4 小时前
Linux--进程池
linux·c++·经验分享·笔记·学习方法
QT 小鲜肉4 小时前
【QT/C++】Qt网络编程进阶:UDP通信和HTTP请求的基本原理和实际应用(超详细)
c语言·网络·c++·笔记·qt·http·udp
实心儿儿5 小时前
C++ —— list
开发语言·c++
仟千意5 小时前
C++:c++基础知识
c++
IT教程资源C5 小时前
(N_152)基于java贪吃蛇游戏5
游戏
木木木丫6 小时前
嵌入式项目:韦东山驱动开发第六篇 项目总结——显示系统(framebuffer编程)
c语言·c++·驱动开发·dsp开发
mit6.8246 小时前
[HDiffPatch] 补丁算法 | `patch_decompress_with_cache` | `getStreamClip` | RLE游程编码
c++·算法
杨筱毅6 小时前
【穿越Effective C++】条款13:以对象管理资源——RAII原则的基石
开发语言·c++·effective c++