Please enable Javascript to view the contents

UE4 中一种 Blueprint&C++ 统一化接口的小技巧

 ·  ☕ 1 分钟

问题描述

    在ue4开发中本人之前一直有一种接口定义的困境,定义支持蓝图的接口吧在代码里用着不舒服,有点影响开发效率。定义只支持C++的接口吧蓝图还要用。
后来翻 GameplayAbility 插件的源码的时候发现人家的解决方案挺简单有效的,特此拿来借鉴一下。

问题的解决方式

在 GameplayAbility 插件中定义了一个 IAbilitySystemInterface 接口,该接口只有一个普通的 C++ 纯虚函数。这种定义也是我们在代码里用着比较舒服的。缺点就是本身在蓝图中用不了。

1
2
3
4
5
6
7
class GAMEPLAYABILITIES_API IAbilitySystemInterface
{
	GENERATED_IINTERFACE_BODY()

	/** Returns the ability system component to use for this actor. It may live on another actor, such as a Pawn using the PlayerState's component */
	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const = 0;
};

为了支持蓝图,它的做法是在蓝图函数库中定义一个相同功能的静态函数:

1
2
	UFUNCTION(BlueprintPure, Category = Ability)
	static UAbilitySystemComponent* GetAbilitySystemComponent(AActor *Actor);

从蓝图侧传入Actor然后在代码里面判断Actor是否实现了接口,如果实现了直接调用接口,没有的话还可以通过遍历组件找。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
	if (Actor == nullptr)
	{
		return nullptr;
	}

	const IAbilitySystemInterface* ASI = Cast<IAbilitySystemInterface>(Actor);
	if (ASI)
	{
		return ASI->GetAbilitySystemComponent();
	}

	if (LookForComponent)
	{
		/** This is slow and not desirable */
		ABILITY_LOG(Warning, TEXT("GetAbilitySystemComponentFromActor called on %s that is not IAbilitySystemInterface. This slow!"), *Actor->GetName());

		return Actor->FindComponentByClass<UAbilitySystemComponent>();
	}

	return nullptr;

个人感觉这种方式比直接在接口文件中直接定义蓝图可用的接口灵活很多。

分享

saberuster
作者
saberuster
一个喜欢编程和折腾的追风少年