112. UE5 GAS RPG 制作高亮接口

我们在之前,实现过高亮的效果,之前,高亮只用在了敌人身上,鼠标悬停到敌人身上时,敌人身上能够出现红色的描边。在这一篇里,我们想将高亮描边功能单独成为一个接口,能够将其应用到更多地方。
首先我们回忆一下之前如何实现此功能,此功能需要使用自定义深度来实现,通过后处理,我们需要开启自定义深度,在项目设置-渲染里找到。
在这里插入图片描述
在场景里添加后处理体积,并在后期处理材质里添加自定义的材质。
在这里插入图片描述
这个材质有两个地方我们可以去修改,如果需要的小伙伴可以通过加群获取
一个是修改描边大小
在这里插入图片描述
另一个是设置自定义数值对应的颜色
在这里插入图片描述

创建高亮接口

先创建一个新的接口
在这里插入图片描述
命名为高亮接口
在这里插入图片描述
将之前敌人接口里的开启和关闭高亮的的函数移动到高亮接口里来,并将其设置为蓝图类型,以后在蓝图中也可以实现对应的添加接口的操作。
敌人接口的对应的高亮相关函数可以去掉了。

// 版权归暮志未晚所有。

#pragma once

#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "HighLightInterface.generated.h"

// This class does not need to be modified.
UINTERFACE(MinimalAPI, BlueprintType)
class UHighLightInterface : public UInterface
{
	GENERATED_BODY()
};

/**
 * 
 */
class RPG_API IHighLightInterface
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
	
	//高亮 描边
	UFUNCTION(BlueprintNativeEvent)
	void HighlightActor();
	
	//取消高亮 描边
	UFUNCTION(BlueprintNativeEvent)
	void UnHighlightActor(); 
};

然后我们先复原之前的敌人红色描边效果,让敌人类继承此接口
在这里插入图片描述
修改继承函数
在这里插入图片描述
将实现里的函数名也修改掉
在这里插入图片描述
接着,我们编译打开蓝图,在蓝图里,实现通过蓝图对检查点添加此功能,需要打开类设置,添加高亮接口
在这里插入图片描述
然后在蓝图事件图标里,实现上面代码实现的功能。如果模型是不可读的,我们需要将指针对象移到protect里,然后添加BlueprintReadOnly标签。
在这里插入图片描述

修改鼠标拾取逻辑

我们想实现更多的拾取功能,需要将PlayerController里的鼠标拾取的逻辑修改掉。
首先我们在PlayerController顶部增加一个枚举,这里指定了类型,不会污染全局命名,缺点就是指定时需要携带枚举类。

//鼠标拾取目标的状态枚举
enum class ETargetingStatus : uint8
{
	//敌人
	TargetingEnemy,
	//鼠标拾取的目标非敌人
	TargetingNonEnemy,
	//无
	NotTargeting
};

接着我们修改鼠标拾取的相关参数
在这里插入图片描述
我们首先修改CursorTrace函数,这个函数会在每次帧更新里调用,用于鼠标拾取。
代码与之前相比主要是鼠标拾取到了对象,我们要转换为高亮接口,Actor高亮也是通过接口去调用。

void ARPGPlayerController::CursorTrace()
{
	//判断当前事件是否被阻挡,如果事件被阻挡,则清除相关内容
	if(GetASC() && GetASC()->HasMatchingGameplayTag(FRPGGameplayTags::Get().Player_Block_CursorTrace))
	{
		if(IsValid(ThisActor)) IHighLightInterface::Execute_UnHighlightActor(ThisActor);
		if(IsValid(LastActor)) IHighLightInterface::Execute_UnHighlightActor(LastActor);
		ThisActor = nullptr; 
		LastActor = nullptr;
		return;
	}

	//如果当前处于魔法范围指示阶段,将忽略掉场景中的角色
	const ECollisionChannel TraceChannel = IsValid(MagicCircle) ? ECC_EXCLUDEPLAYERS_CHANNEL : ECC_Visibility;
	
	GetHitResultUnderCursor(TraceChannel, false, CursorHit); //获取可视的鼠标命中结果
	if(!CursorHit.bBlockingHit) return; //如果未命中直接返回

	LastActor = ThisActor;
	//获取拾取的Actor,判断Actor是否继承高亮接口
	if(IsValid(CursorHit.GetActor()) && CursorHit.GetActor()->Implements<UHighLightInterface>())
	{
		ThisActor = CursorHit.GetActor();
	}
	else
	{
		ThisActor = nullptr;
	}

	//如果两次拾取的目标不同,将修改高亮目标
	if(ThisActor != LastActor)
	{
		if(IsValid(ThisActor)) IHighLightInterface::Execute_HighlightActor(ThisActor);
		if(IsValid(LastActor)) IHighLightInterface::Execute_UnHighlightActor(LastActor);
	}
	
}

接着修改鼠标按下事件,如果鼠标左键按下,根据ThisActor的类型,设置不同的状态

void ARPGPlayerController::AbilityInputTagPressed(const FGameplayTag InputTag)
{
	//处理判断按下事件是否被阻挡
	if(GetASC() && GetASC()->HasMatchingGameplayTag(FRPGGameplayTags::Get().Player_Block_InputPressed))
	{
		return;
	}
	//判断鼠标左键,并处理移动相关
	if(InputTag.MatchesTagExact(FRPGGameplayTags::Get().InputTag_LMB))
	{
		//ThisActor为鼠标悬停在敌人身上才会有值
		if(IsValid(ThisActor))
		{
			if(ThisActor->Implements<UEnemyInterface>())
			{
				//继承敌人接口,目标为敌人
				TargetingStatus = ETargetingStatus::TargetingEnemy;
			}
			else
			{
				//无敌人接口,基本为场景静态物体
				TargetingStatus = ETargetingStatus::TargetingNonEnemy;
			}
		}
		else
		{
			//目标不存在,设置为无目标状态
			TargetingStatus = ETargetingStatus::NotTargeting;
		}

		bAutoRunning = false;
		FollowTime = 0.f; //重置统计的时间
	}
	//调用ASC内创建的键位按下事件
	if(GetASC()) GetASC()->AbilityInputTagPressed(InputTag);
}

鼠标抬起这里,判断状态为非敌人枚举,可以触发寻路逻辑
在这里插入图片描述
而在鼠标按住时,要攻击敌人,则需要判断状态为敌人才可。
在这里插入图片描述
接着在UE里,测试检查点是否实现了描边功能。
在这里插入图片描述

### UE5 中基于 GAS 架构的 RPG 游戏开发 #### 创建角色属性系统 在 Unreal Engine 5 (UE5) 的游戏中,Gameplay Ability System (GAS) 提供了一种强大的方式来管理游戏角色的能力和属性。为了创建一个基本的角色属性系统,在项目设置中启用插件 `GameplayAbilities` 和 `GameplayTags` 是必要的[^1]。 定义自定义属性集类继承于 `UAttributeSet` 类,用于表示玩家的生命值、法力值和其他统计信息: ```cpp // MyCharacterAttributes.h #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "AbilitySystemComponent.h" #include "MyCharacterAttributes.generated.h" /** * */ UCLASS() class MYGAME_API UMyCharacterAttributes : public UAttributeSet { GENERATED_BODY() public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData Health; ATTRIBUTE_ACCESSORS(UMyCharacterAttributes, Health) // Other attributes like Mana, Stamina can be added here similarly. }; ``` #### 实现能力框架 接着实现具体的游戏玩法功能——即“能力”。这涉及到编写新的 C++ 或蓝图脚本文件以扩展 `UGameplayAbility` 基础类。这些对象封装了执行特定动作所需的数据逻辑,比如攻击敌人或施放魔法技能等操作。 对于每个想要赋予给角色的新能力,都需要单独创建对应的子类实例并配置其行为参数。例如,可以构建名为 `AGrenadeThrowAbility` 的投掷手雷能力类,并通过编辑器界面指定冷却时间、消耗资源量以及效果范围等相关设定。 #### 设计任务与奖励机制 当考虑如何在游戏中引入任务系统时,可以通过 GAS 来追踪目标进度并向完成挑战的用户提供反馈。利用 `FGameplayTagContainer` 结合标签查询表达式匹配条件触发事件,从而动态调整难度等级或是解锁新区域等内容更新。 此外,还可以借助该系统的灵活性为不同类型的成就设立专属奖赏池,允许开发者轻松定制各种形式的经验加成、道具掉落概率提升等奖励措施。 #### 集成用户界面显示 为了让玩家能够直观了解当前状态变化情况,应该同步修改 HUD 组件以便实时反映最新数值变动。通常做法是在屏幕角落固定位置绘制小型图标条形图等形式展示生命槽、能量棒之类的关键指标;同时也可以采用弹窗提示框的方式告知重要消息通知。 最后值得注意的是,由于 GAS 自身并不直接处理 UI 层面的工作,因此这部分工作往往需要额外投入一定精力去精心打磨用户体验细节部分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值