3.1 KiB
Raw Blame History

AllowPrivateAccess

  • 功能描述: 允许一个在C++中private的属性可以在蓝图中访问。
  • 使用位置: UPROPERTY
  • 元数据类型: bool
  • 关联项: BlueprintProtected
  • 常用程度: ★★★★★

允许一个在C++中private的属性可以在蓝图中访问。

AllowPrivateAccess的意义是允许这个属性在C++是private的不允许C++子类访问,但又允许其暴露到蓝图中访问。

测试代码:

public:
	//CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPublic 
	UPROPERTY(BlueprintReadWrite)
	int32 MyNativeInt_NativePublic;
private:
	//CPF_ZeroConstructor | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPrivate 
	//error : BlueprintReadWrite should not be used on private members
	UPROPERTY()
	int32 MyNativeInt_NativePrivate;

	//(AllowPrivateAccess = TRUE, Category = MyFunction_Access, ModuleRelativePath = Function/MyFunction_Access.h)
	//CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPrivate 
	UPROPERTY(BlueprintReadWrite, meta = (AllowPrivateAccess = true))
	int32 MyNativeInt_NativePrivate_AllowPrivateAccess;

在MyNativeInt_NativePrivate上如果尝试加上BlueprintReadWrite或BlueprintReadOnly都会触发UHT编译报错。

蓝图里的效果:

默认情况下MyNativeInt_NativePrivate_AllowPrivateAccess在蓝图里的访问权限和MyNativeInt_NativePublic一致。

如果读者想要修改改属性在蓝图中的访问权限则可以配合加上BlueprintProtected和BlueprintPrivate。

Untitled

原理:

UHT在识别属性的BlueprintReadWrite或BlueprintReadOnly标识符的时候会同时检测是否有AllowPrivateAccess没有的话会触发报错。

因此AllowPrivateAccess的意义其实只是在阻止UHT的报错这层检测报错过了之后属性上的BlueprintReadWrite或BlueprintReadOnly就会被识别并发挥作用从而可以在蓝图中访问。

	private static void BlueprintReadWriteSpecifier(UhtSpecifierContext specifierContext)
	{
			bool allowPrivateAccess = context.MetaData.TryGetValue(UhtNames.AllowPrivateAccess, out string? privateAccessMD) && !privateAccessMD.Equals("false", StringComparison.OrdinalIgnoreCase);
			if (specifierContext.AccessSpecifier == UhtAccessSpecifier.Private && !allowPrivateAccess)
			{
				context.MessageSite.LogError("BlueprintReadWrite should not be used on private members");
			}
	}
	
	private static void BlueprintReadOnlySpecifier(UhtSpecifierContext specifierContext)
	{
			bool allowPrivateAccess = context.MetaData.TryGetValue(UhtNames.AllowPrivateAccess, out string? privateAccessMD) && !privateAccessMD.Equals("false", StringComparison.OrdinalIgnoreCase);
			if (specifierContext.AccessSpecifier == UhtAccessSpecifier.Private && !allowPrivateAccess)
			{
				context.MessageSite.LogError("BlueprintReadOnly should not be used on private members");
			}
	}