当前位置: 首页 > news >正文

虚幻引擎5 GAS开发俯视角RPG游戏 P07-08 点击移动

目标:当鼠标左键一直按住时,角色会跟随鼠标移动

1.添加一些变量

Source/CC_Aura/Public/Player/CC_PlayerController.h

/*鼠标点击移动*/
#pragma region ClickToMoveprivate:FVector CachedDestination = FVector::ZeroVector;	//追击的目的地float FollowTime = 0.f;		//鼠标按住的时间float ShortPressThreshold = 0.5f;		//短按阈值bool bAutoRunning =false;		//是否自动追踪bool bTargetting = false;		//是否瞄准目标UPROPERTY(EditDefaultsOnly, Category="CC|ClickToMove")float AutoRunAcceptanceRadius = 50.f;		//自动追踪到达目的地的半径后停止UPROPERTY(VisibleAnywhere, Category="CC|ClickToMove")TObjectPtr<USplineComponent> Spline;		//样条曲线#pragma endregion	

构造函数添加样条曲线组件:

ACC_PlayerController::ACC_PlayerController()
{bReplicates = true;		//确保可复制Spline = CreateDefaultSubobject<USplineComponent>("Spline");}

2.当输入刚刚按住时,判断:

(1)是否是鼠标左键?

(2)鼠标左键按住的是不是敌人类?

(3)需不需要自动追踪?

/*开始按下*/
void ACC_PlayerController::AbilityInputTagPressed(FGameplayTag InputTag)
{/*如果是鼠标左键*/if (InputTag.MatchesTagExact(CC_GameplayTags::Input_LMB)){bTargetting = ThisActor ? true : false;		//是否有敌人?bAutoRunning = false;		//短按,不需要自动追踪}
}

3.在AbilityInputTagHold(FGameplayTag InputTag)函数中,先判断是不是鼠标左键,要是不是的,就正常触发技能:

/*保持*/
void ACC_PlayerController::AbilityInputTagHold(FGameplayTag InputTag)
{/*如果不是鼠标左键*/if (!InputTag.MatchesTagExact(CC_GameplayTags::Input_LMB)){if (GetCC_AbilitySystemComponent() == nullptr) return;GetCC_AbilitySystemComponent()->AbilityInputTagHeld(InputTag);return;}

要是鼠标左键,则判断是不是敌人类:

/*如果是鼠标左键*/if (bTargetting)	//是敌人类{if (GetCC_AbilitySystemComponent() == nullptr) return;GetCC_AbilitySystemComponent()->AbilityInputTagHeld(InputTag);return;}

不是敌人类,就跟随鼠标移动:

					//非敌人类FollowTime += GetWorld()->GetDeltaSeconds();FHitResult Hit;if (GetHitResultUnderCursor(ECC_Visibility, false, Hit)){CachedDestination = Hit.ImpactPoint;}if (APawn* ControlledPawn = GetPawn<APawn>()){const FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();ControlledPawn->AddMovementInput(WorldDirection);}

其中:

if (GetHitResultUnderCursor(ECC_Visibility, false, Hit)){CachedDestination = Hit.ImpactPoint;}

这段代码用于在Unreal Engine中实现鼠标点击位置检测功能。通过射线检测获取鼠标光标下的碰撞点坐标,并将该坐标存储为缓存目标位置。

UPROPERTY()
FVector_NetQuantize ImpactPoint;

用于存储碰撞检测中的实际接触点坐标

GetSafeNormal()

向量安全归一化方法实现,用于获取向量的单位向量同时避免除零错误

源码:

Source/CC_Aura/Public/Player/CC_PlayerController.h:

// 版权归陈超所有#pragma once#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "CC_PlayerController.generated.h"class USplineComponent;
class UCC_AbilitySystemComponent;
struct FGameplayTag;
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;UPROPERTY()TObjectPtr<UCC_AbilitySystemComponent> CC_AbilitySystemComponent;		//能力系统组件UCC_AbilitySystemComponent* GetCC_AbilitySystemComponent();/*鼠标追踪* 1.高亮敌人类*/
#pragma region CurserTrace
private://鼠标追踪变量TScriptInterface<ICC_EnemyInterface> LastActor;	//上一帧拾取的接口指针TScriptInterface<ICC_EnemyInterface> ThisActor;	//当前帧拾取的接口指针void CurserTrace();	//鼠标追踪函数
#pragma endregion/*输入设置* 1.移动输入* 2.能力输入*/
#pragma region Inputs
protected:virtual void SetupInputComponent() override;
private:UPROPERTY(EditAnywhere, Category="CC|Input")TObjectPtr<UDataAsset_InputConfig> DataAssetInputConfig;void Move(const struct FInputActionValue& InputActionValue);void AbilityInputTagPressed(FGameplayTag InputTag);		//按下void AbilityInputTagReleased(FGameplayTag InputTag);	//结束void AbilityInputTagHold(FGameplayTag InputTag);		//持续
#pragma endregion/*鼠标点击移动*/
#pragma region ClickToMoveprivate:FVector CachedDestination = FVector::ZeroVector;	//追击的目的地float FollowTime = 0.f;		//鼠标按住的时间float ShortPressThreshold = 0.5f;		//短按阈值bool bAutoRunning =false;		//是否自动追踪bool bTargetting = false;		//是否瞄准目标UPROPERTY(EditDefaultsOnly, Category="CC|ClickToMove")float AutoRunAcceptanceRadius = 50.f;		//自动追踪到达目的地的半径后停止UPROPERTY(VisibleAnywhere, Category="CC|ClickToMove")TObjectPtr<USplineComponent> Spline;		//样条曲线#pragma endregion};

Source/CC_Aura/Private/Player/CC_PlayerController.cpp:

// 版权归陈超所有#include "Player/CC_PlayerController.h"#include "AbilitySystemBlueprintLibrary.h"
#include "AbilitySystem/CC_AbilitySystemComponent.h"
#include "CC_GameplayTags.h"
#include "Components/SplineComponent.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
#include "Input/CC_InputComponent.h"
#include "Interations/CC_EnemyInterface.h"ACC_PlayerController::ACC_PlayerController()
{bReplicates = true;		//确保可复制Spline = CreateDefaultSubobject<USplineComponent>("Spline");}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 2ThisActor->HighlightActor();} // else case 1}else{if(ThisActor == nullptr){//case 3LastActor->UnHighlightActor();}else{if(LastActor != ThisActor){//case 4LastActor->UnHighlightActor();ThisActor->HighlightActor();} //else case 5}}	
}void ACC_PlayerController::BeginPlay()
{Super::BeginPlay();//设置鼠标光标bShowMouseCursor = true; //游戏中是否显示鼠标光标DefaultMouseCursor = EMouseCursor::Default; //鼠标光标的样式FInputModeGameAndUI InputModeData;InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock); //将鼠标锁定在视口内InputModeData.SetHideCursorDuringCapture(false); //鼠标被捕获时是否隐藏SetInputMode(InputModeData); //设置给控制器}UCC_AbilitySystemComponent* ACC_PlayerController::GetCC_AbilitySystemComponent()
{if (CC_AbilitySystemComponent == nullptr){UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(GetPawn<APawn>());CC_AbilitySystemComponent = Cast<UCC_AbilitySystemComponent>(AbilitySystemComponent);}return CC_AbilitySystemComponent;
}//设置输入组件函数(重载)
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->BindInputAction(DataAssetInputConfig, CC_GameplayTags::Input_Move, ETriggerEvent::Triggered, this, &ThisClass::Move); //绑定移动事件CC_InputComponent->BindAbilityAction(DataAssetInputConfig, this, &ThisClass::AbilityInputTagPressed, &ThisClass::AbilityInputTagReleased, &ThisClass::AbilityInputTagHold);
}//移动事件的返回函数
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到1if(APawn* ControlledPawn = GetPawn<APawn>()){ControlledPawn->AddMovementInput(ForwardDirection, InputAxisVector.Y);ControlledPawn->AddMovementInput(RightDirection, InputAxisVector.X);}}/*开始按下*/
void ACC_PlayerController::AbilityInputTagPressed(FGameplayTag InputTag)
{/*如果是鼠标左键*/if (InputTag.MatchesTagExact(CC_GameplayTags::Input_LMB)){bTargetting = ThisActor ? true : false;		//是否有敌人?bAutoRunning = false;		//不需要自动追踪}
}/*释放*/
void ACC_PlayerController::AbilityInputTagReleased(FGameplayTag InputTag)
{if (GetCC_AbilitySystemComponent() == nullptr) return;GetCC_AbilitySystemComponent()->AbilityInputTagReleased(InputTag);
}/*保持*/
void ACC_PlayerController::AbilityInputTagHold(FGameplayTag InputTag)
{/*如果不是鼠标左键*/if (!InputTag.MatchesTagExact(CC_GameplayTags::Input_LMB)){if (GetCC_AbilitySystemComponent() == nullptr) return;GetCC_AbilitySystemComponent()->AbilityInputTagHeld(InputTag);return;}/*如果是鼠标左键*/if (bTargetting)	//是敌人类{if (GetCC_AbilitySystemComponent() == nullptr) return;GetCC_AbilitySystemComponent()->AbilityInputTagHeld(InputTag);return;}//非敌人类FollowTime += GetWorld()->GetDeltaSeconds();FHitResult Hit;if (GetHitResultUnderCursor(ECC_Visibility, false, Hit)){CachedDestination = Hit.ImpactPoint;}if (APawn* ControlledPawn = GetPawn<APawn>()){const FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();ControlledPawn->AddMovementInput(WorldDirection);}
}

http://www.dtcms.com/a/586110.html

相关文章:

  • 泰安公司做网站学做面包的网站
  • 陕西省建设工程信息网官网门户网站优化报价
  • 【代码审计】newbee-mall 三处安全问题分析
  • MySQL索引添加与删除方法详解
  • Node-RED:5分钟快速上手:安装与环境配置
  • 青海移动网站建设wordpress 显示标题
  • 3.1.STM32-GPIO通用输入输出口
  • 东营 网站建设公司网站项目设计
  • [论文阅读] AI + 职业教育 | 从框架到实践:职业院校教师人工智能素养提升的完整方案
  • 零基础入门C语言之C语言实现数据结构之顺序表应用
  • 网站建设 淘宝详情东莞网站建设哪里好
  • 大连的网站设计公司wordpress支持页面模版
  • 孤能子视角:房地产,独一无二的“社会场域能力“
  • 【AI安全】检索增强生成(RAG)
  • qt中以this为父窗口和以centralwidget为父窗口有什么区别
  • xxx网站建设与优化推广做网站市场报价步登顶
  • 【Spring Boot】REST与RESTful详解,基于Spring Boot的RESTful API实现
  • 2025年渗透测试面试题总结-234(题目+回答)
  • Z-Wave物联网网关开发专用 SDK - Unify
  • 3g微网站北京住房和城乡建设官方网站
  • 济南一哥网站建设网站建设明薇通网络服务好
  • 弱函数 vs 回调函数:本质区别解析
  • 2024年 国内养老机构及床位数据
  • 建设部标准规范网站wordpress防止采集
  • 4.3 IP: Internet Protocol
  • 一般购物网站项目深圳做网站比较好天涯
  • 网站建设的重点难点企业简介 网站建设
  • PostgreSQL 19新特性之GROUP BY ALL
  • 技能补全之Python AES GCM 加密存储
  • NCP13992 CS 分压计算