UE5 通过接口实现角色描边效果

接口不能够被实例化,不能够在内部书写函数的逻辑和设置属性,只能够被继承使用。它能够让不同的类实现有相同的函数,继承接口的类必须实现接口的函数。

并且,我们可以在不同的类里面的函数实现也不同,比如A类描边是红色,B类的描边是绿色的,描边的调用都使用一个函数调用。

创建接口类

右键添加c++类,在常见类中找到Unreal接口,创建一个Enemy的接口类

cpp 复制代码
// 版权归暮志未晚所有。

#pragma once

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

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

/**
 * 
 */
class AURA_API IEnemyInterface
{
	GENERATED_BODY()

	// 向此类添加接口函数(虚函数),继承此接口的类都将需要继承并实现这些函数。
public:
	virtual void HighlightActor() = 0; //高亮
	virtual void UnHighlightActor() = 0; //取消高亮
};

在接口类EnemyInterface.h中,我们增加了两个虚函数,继承此接口的类需要实现高亮函数和取消高亮函数

类实现接口

接着让敌人类继承接口

如果你只继承,不实现相关函数,会发现编译时提示报错。

cpp 复制代码
// 版权归暮志未晚所有。

#pragma once

#include "CoreMinimal.h"
#include "Character/CharacterBase.h"
#include "Interaction/EnemyInterface.h"
#include "Enemy.generated.h"

/**
 * 
 */
UCLASS()
class AURA_API AEnemy : public ACharacterBase, public IEnemyInterface
{
	GENERATED_BODY()
	
public:
	virtual void HighlightActor() override; //高亮
	virtual void UnHighlightActor() override; //取消高亮

	UPROPERTY(BlueprintReadOnly) //蓝图可读
	bool bHighlighted = false; //是否高亮
};

我们需要在类里面继承函数,并在cpp里面定义相关逻辑。这里先定义了一个变量,用来获取当前角色是否需要高亮

cpp 复制代码
// 版权归暮志未晚所有。


#include "Character/Enemy.h"

void AEnemy::HighlightActor()
{
	bHighlighted = true;
}

void AEnemy::UnHighlightActor()
{
	bHighlighted = false;
}

在cpp中,高亮将此值设置为true,取消高亮设置为false。

通过鼠标拾取设置敌人是否高亮

设置敌人高亮,我们可以通过在帧更新里面,通过获取鼠标拾取到的对象,对对象进行判断是否设置高亮。

在playercontroller中,我们覆盖帧更新回调,鼠标位置追踪拾取函数,以及两个变量去记录当前鼠标拾取到的内容。

cpp 复制代码
//帧更新
void APlayerControllerBase::PlayerTick(float DeltaTime)
{
	Super::PlayerTick(DeltaTime);

	CursorTrace();
}

帧更新里面,只需要增加对鼠标帧更新的调用。

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

	LastActor = ThisActor;
	ThisActor = Cast<IEnemyInterface>(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
		}
	}
	
}

而鼠标位置追踪拾取函数,首先就是先通过函数获取可视的内容,对拾取的内容判断是否继承至IEnemyInterface,然后根据情况进行高亮和非高亮的设置。

在蓝图中根据变量设置可视效果

首先,我需要先在debug模式下测试设置高亮是否有效果,有了变量bHighlighted后,我们可以在敌人的蓝图中获取它的变量,如果为true,我们将在敌人身上添加一个球代表它需要高亮。

在敌人的事件图表中,帧更新中,增加对Hightlighted的判断,如果为true,则在敌人位置创建一个球

为了能够被鼠标拾取到,我们需要将敌人模型的检测相应可视设置为阻挡。

运行点击~ 输入show Collision将会显示所有的碰撞体,再输入一次,将隐藏掉所有没必要的碰撞体显示。

接下来放置几个敌人进行测试,会发现鼠标悬浮在谁身上,就会生成一个球。

使用后处理实现对模型的描边

在ue里面实现描边有多种方法,大家经常使用的方法就是使用后处理描边。

首先在场景内添加一个后处理体积

将后处理体积影响范围设置为无限

然后在后期处理材质这里,将材质添加进来

后处理材质逻辑大概如此,这里不再展开将了,原理就是通过卷积的方式,采样进行比对,分析出描边区域,然后根据设置的颜色显示。需要用到自定义深度功能。

在项目设置里面开启基于模版的自定义深度

在材质中,如果自定义深度为250,那么它的模型周围会出现描边效果,那么,最后一步,我们将需要描边的模型的自定义深度开启,并设置为250,则实现当前效果。

在前面,我们在敌人的基类里面实现了设置高亮以及取消高亮,只要我们在代码中实现,对自定义深度通道修改以及自定义深度模板值的修改,就可以实现当前的高亮效果。

cpp 复制代码
// 版权归暮志未晚所有。


#include "Character\EnemyBase.h"

#include "Aura/Aura.h"

AEnemyBase::AEnemyBase()
{
	GetMesh()->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); //设置可视为阻挡
}

void AEnemyBase::HighlightActor()
{
	GetMesh()->SetRenderCustomDepth(true);
	GetMesh()->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
	Weapon->SetRenderCustomDepth(true);
	Weapon->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
}

void AEnemyBase::UnHighlightActor()
{
	GetMesh()->SetRenderCustomDepth(false);
	Weapon->SetRenderCustomDepth(false);
}

设置角色的模型和武器的模型的自定义深度和自定义深度模版值,为了方便以后迭代修改,红色的值直接定义在了CUSTOM_DEPTH_RED宏中。

并且,为了爆炸角色模型能够被鼠标拾取到,我们直接在构造时直接修改了设置可见性的拾取。

相关推荐
星火撩猿1 小时前
常见游戏引擎介绍与对比
unity·ue5·游戏引擎·godot
清流君3 小时前
【MySQL】数据库 Navicat 可视化工具与 MySQL 命令行基本操作
数据库·人工智能·笔记·mysql·ue5·数字孪生
Involuter14 小时前
UE5 Assimp 自用
ue5
电子云与长程纠缠16 小时前
Unreal Niagara制作SubUV贴图翻页动画
学习·ue5·编辑器·贴图·niagara
子燕若水20 小时前
“Daz to Unreal”将 G8 角色(包括表情)从 daz3d 导入到 UE5。在 UE5 中,我发现使用某个表情并与闭眼混合后,上眼睑出现了问题
3d·ue5
半天法师1 天前
UE5.2+VarjoXR3,Lumen、GI、Nanite无效的两种解决方案
ue5·xr·vr
ue星空1 天前
UE5摄像机画面没有填充满屏幕有黑边
ue5
李詹2 天前
游戏开发核心技术解析——从引擎架构到攻防体系的完整技能树
架构·ue5·游戏引擎·游戏程序·3dsmax·虚幻
子燕若水2 天前
UE5的 Modify Curve 蓝图节点
ue5
人宅4 天前
UE5有些场景的导航生成失败解决方法
ue5