UE_Angelscript 绑定篇——避坑:不踩一下,怎知是坑#

本篇一条一条地罗列,未必都分门别类了,权当避坑小贴士。

有一些内容在绑定篇的其他地方也会提到,这里再提的话,相当于划重点了吧。

不要相信 UStruct 的继承,AS 只认当前的 UStruct#

按照 AS 的绑定逻辑,UStruct 如果没有标记为 BlueprintType 或者没有包含暴露给蓝图的内容(继承的不算),那么,这个 UStruct 不会进入 AS 的绑定清单。

也就是说,你会发现,这个 UStruct 在蓝图里用得好好的(因为它的父类暴露给蓝图了),但是 AS 里查无此类!

例如

struct FAnimUpdateContext : public FAnimExecutionContext

不要相信 UStruct 的继承,给它增加绑定功能,你得将子子孙孙都一起处理#

如果某个 UStruct 有一群子孙,你给这个爷爷辈的 UStruct 增加了绑定功能,不管是手工绑定还是 Mixin 绑定,都只对你所操作的 UStruct 生效。

总之一句话,UStruct 的继承,在 AS 里就相当于没有。是的,AS 里写代码,UStruct 是不能有继承的,甚至不可以写函数(如果非要给增加函数,用 Mixin 大法)。

Meta 里有 BlueprintInternalUseOnly ,AS 就不认了#

meta = (BlueprintInternalUseOnly = "true") 这个标记加上后,AS 就访问不到这个函数了。

// 这个函数没办法被AS访问到
    UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
    void TestBlueprintInternalUseOnly()
    {
       UE_LOG(LogTemp,Warning,TEXT("Test BlueprintInternalUseOnly UFUNCTION Show"));
    }
};

这个本来是限制蓝图的使用范围的,AS 是接过蓝图的大部分内容的,现在同样作用于 AS 。但是 AS 又没有蓝图的一些特性,比如识别使用范围,导致这类函数相当于不能调用。

比较好的解决方式就是 Mixin 绑定,或者新写一些蓝图库函数(针对一些静态函数)。

另外一个方式是通过各种方式,去掉 BlueprintInternalUseOnly。

最后是修改 AS 脚本插件的代码,在 Bind_BlueprintCallable 里放行 BlueprintInternalUseOnly,全部放行就注释掉限制 BlueprintInternalUseOnly 绑定的代码,部分放行就得写各种判断。

如果这个 UClass 被标记为 MinimalAPI,而 BlueprintInternalUseOnly 恰好又被加上了你想调用的 UFUNCTION。因为你写的 Mixin 函数一般在其他模块里,那么正常通过 cpp 是不能调用这个函数的。怎么办?此时,就可以祭出反射大法了,通过反射可以获取、调用已知函数名的成员函数。

针对这个问题,详细的解决方案总结看这里,会列出详细的代码: UE_Angelscript 绑定篇——解决方案:BlueprintInternalUseOnly 函数的增强处理方式

AS 绑定的是原始函数名,而不是 Display 名。#

原始函数名会根据规则掐头去尾。 这种情况下,蓝图显示的名称和 AS 里的名称就不一致了。

如蓝图里的 Multi Line Trace By Channel 的原始函数名是 LineTraceMulti, Line Trace By Channel 的原始函数名是 LineTraceSingle。

有时候看到一些蓝图函数,想按图索骥,发现找不到函数名,这时只能跳转到 cpp 的代码来查看这个函数真正名称是什么。

AS 的 TMap 的 key 会限制一些绑定的原生 struct#

举例子:FObjectKey 绑定后,仍然无法用于 TMap 的 key。会报错如下:

Attempting to instantiate invalid template type 'TMap<FObjectKey,FGameplayAbilitySpecHandle>': Containers cannot be nested in other containersas

不知道是不是因为它没有 public 的成员。

解决方案,是用一个 FObjectKeyWrapper 包装起来,实现 GetTypeHash 函数以及一批重载操作符的比较函数。

更新:更好地绑定方案,需要在手工绑定时候将这个类关联一个继承自 TAngelscriptCppType 的类,参考如下。此方案适用于 TMap、TArray、TSet。

#include "Binds/Helper_CppType.h"
///// Add this
struct FObjectKeyType : TAngelscriptCppType<FObjectKey>
{
	FString GetAngelscriptTypeName() const override
	{
		return TEXT("FObjectKey");
	}

	bool GetCppForm(const FAngelscriptTypeUsage& Usage, FCppForm& OutCppForm) const override
	{
		OutCppForm.CppType = GetAngelscriptTypeName();
		return true;
	}
};

AS_FORCE_LINK FAngelscriptBinds::FBind Bind_ObjectKey((int32)FAngelscriptBinds::EOrder::Late + 100,[]
{
	FBindFlags Flags;
	Flags.bPOD = true;
	FAngelscriptBinds ThisBind = FAngelscriptBinds::ValueClass<FObjectKey>("FObjectKey", Flags);
	///// Add this
	FAngelscriptType::Register(MakeShared<FObjectKeyType>());

Mixin 绑定的时候,this 指针 的 const 标识符不能丢#

需要记住,const 不会凭空丢失。Mixin 绑定的时候,const 如果修饰 this 指针,那么 Mixin 的静态函数的首个参数,也必须带 const 。

举例如下。

//  这个要被绑定的 FGameplayAttribute 的原始函数
float GetNumericValueChecked(const UAttributeSet* Src) const;

// 这是 FGameplayAttribute 的一个 Mixin 函数
UFUNCTION(BlueprintCallable)
static float BP_GetNumericValueChecked(const FGameplayAttribute& GameplayAttribute, const UAttributeSet* Src)
{
    return GameplayAttribute.GetNumericValueChecked(Src);
};

// 绑定后,AS 里会将这个函数显示为
float32 FGameplayAttribute.GetNumericValueChecked(const UAttributeSet Src) const

// 总结:Mixin 函数 的 const FGameplayAttribute& GameplayAttribute 的 const 变成了 AS 里函数签名末尾的 const ,表示不修改类成员。最终的形式和原始函数基本一致。

UGameplayMessageSubsystem 尽量不要 cpp 和 AS 混用#

UGameplayMessageSubsystem 是一个不错的解耦 Subsystem ,类似于一个中枢广播系统,发送的信息是各种各样的 UStruct 。可以先看看本专栏的相关文章——UE_Angelscript 之 GameplayMessageSubsystem 与 GameplayTags 。

因为 UGameplayMessageSubsystem 传递的是各种各种的 UStruct ,这些 UStruct 可能在传递的时候出现问题。

就是说,最好不要一个发送信息和接受信息的分别属于 cpp 和 AS,不然可能产生报错。

动画系统的绑定,涉及异步执行的时候,很麻烦#

比如 Lyra 示例项目,采用了异步执行的方案,那些异步调用在蓝图里写起来比较方便,在 AS 里就还没有这类绑定。(或者是我还没研究明白。)

谨慎使用 Delay 函数。AS 里自动绑定好的 Delay 更要谨慎使用。#

AS 里和 cpp 同时类似的 Delay 代码,AS 版本的有时候会导致 Delay 的时间变长。

问题原因,个人推测是 Delay 的机制是阻塞进程,这种阻塞或许与脚本的虚拟机相互影响。

不管什么原因吧,能用 Timer 就用 Timer。

想绑定模板函数?放弃吧,特例出来几个不好么?#

AS 本身不支持模板,类似模板的一些写法,是经过特殊处理的。如果想使用 cpp 里的一些方便的模板函数,可以考虑特例出来几个,通过 Mixin 或者直接写入蓝图函数库。

AS 只是个轻量化的脚本,不用什么都往里面搬运。


×

联系

问题反馈

问题与反馈请提交至 GitHub Issues。

合作

合作事宜请发送邮件至 contact@cuviss.com。

×

关于

服务条款

各插件的许可证见社区贡献页。

网站内容可在注明来源后引用。

软件和文档按“现状”提供,不作任何保证。

Unreal Engine 等第三方项目及名称相关商标归各自所有者所有。soloAS 与 Epic Games、Hazelight 均无关联。

致谢和案例展示请求均不具约束力,详见首页说明。

更新于 2026-10-24

隐私政策

本网站不使用分析工具、Cookie 或跟踪,也没有数据表单或第三方脚本。

网站托管于 GitHub Pages。GitHub 可能按其隐私声明处理标准访问日志。

通过邮件发送的内容会提供给我们;通过 GitHub Issues 发送的内容会提供给 GitHub。

更新于 2026-10-24

目录

页面列表

本页目录