跳至主要內容

F5.1 UPROPERTY-GetOptions

Mr.Si大约 2 分钟u++Specifiers

GetOptions

通过 "Module.Class.Function" 引用外部的静态函数,使得 FString FName 类型的属性 能够动态生成一组有限的选项。


//类内可直接用非静态函数,类外推荐带static关键字
 TArray<FString> GetNames() const
 {
        return {"", "牛逼", "不牛逼"};
 }
 UPROPERTY(EditAnywhere, meta = (GetOptions = "GetNames"))
 FName Names;
 
头像
你是否使用过Enum?
头像
用过怎么了!
UENUM(Meta = (Bitflags))
enum class EColorBits
{
    ECB_Red,
    ECB_Green,
    ECB_Blue
};
头像
没怎么,我接着问你,你是否使用过FName或FString?
头像
用过怎么了?

UPROPERTY(BlueprintReadWrite,VisibleAnywhere)
FName Name;

头像
那我问你,Enum是不是可以在编辑器中下拉选择某一项?
头像
对啊!难不成FName或FString也能下拉选项???
头像
有的,哥们有的!
头像
不明觉厉!
头像

哥们可以在UPROPERTY里的meta中加入GetOptions = "函数名"

 TArray<FString> GetNames() const
 {
        return {"", "牛", "不牛"};
 }
 UPROPERTY(EditAnywhere, meta = (GetOptions = "GetNames"))
 FName Names;
头像
可是,这有个屌用,写死的数据毫无意义呀!

配合UDeveloperSettingsBackedByCVars

头像
年轻人,你可还记得之前说过怎么在设置配置一些默认配置?
头像
搜得寺内!预设一些规则在默认配置中,但这好像涉及跨类调用了。

函数调用

1. 引用外部的静态函数

头像

Module.Class.Function 以官方的UColorInputDeviceProperty为例

2.类内可直接调用

 TArray<FString> GetNames() const
 {
        return {"", "牛", "不牛"};
 }
 UPROPERTY(EditAnywhere, meta = (GetOptions = "GetNames"))
 FName Names;

案例

头像

出于生产需要,资产类中配置一些资产片段(TMap)。例如:希望根据PrimaryAssetType指定一套片段规则


#if WITH_EDITOR
/**
*UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category=Display, Instanced, meta = (GetOptions = "GetNameOptions"))
*TMap<FName, TObjectPtr<UDataFragmentBase>> FragmentMap;
*/
UFUNCTION()
TArray<FName> GetNameOptions() const;

#endif	// WITH_EDITOR
#if WITH_EDITOR
TArray<FName> UDataDefinition::GetNameOptions() const
{
	TArray<FName> Options;
	const UDataSystemSettings* Settings = GetDefault<UDataSystemSettings>();
	if (!Settings) return Options;

	if(bUseGlobalConfig)
	{
		Options = Settings->GlobalFragmentKeys;
	}
	else
	{
		Options = Settings->FragmentKeyPresets.FindRef(GetPrimaryAssetId().PrimaryAssetType).PresetKeys;
	}
	
	return Options;
}
# endif	// WITH_EDITOR

配置类本身是单例

UCLASS(config=Game, defaultconfig, meta=(DisplayName="DataSystemSettings"))
class DATASYSTEM_API UDataSystemSettings : public UDeveloperSettingsBackedByCVars
{
	GENERATED_BODY()

public:
	
	/** 
	 * 按 `PrimaryAssetType` 分类的 Fragment Key 预设映射
	 * - 主要用于不同类型的 `UDataDefinition` 具有不同的 `FragmentMap` Key 下拉选项
	 * - 例如:`装备` 可能有 `PickUp`, `BaseInfo`, `Skin` 等
	 */
	UPROPERTY(EditAnywhere, Config, Category = "Fragment Key Presets")
	TMap<FPrimaryAssetType, FFragmentKeyPreset> FragmentKeyPresets;

	/** 
	 * 全局 Fragment Key 预设(适用于所有 `UDataDefinition`)
	 * - 如果人工勾选bUseGlobalConfig为true,则直接使用这些通用 Key
	 * - 如果 `FragmentKeyPresets` 中没有匹配的 `PrimaryAssetType`,则使用这些通用 Key
	 */
	UPROPERTY(EditAnywhere, Config, Category = "Fragment Key Presets")
	TArray<FName> GlobalFragmentKeys;
	
};
头像
卧槽!我之前还发愁如果用了FName自由度太高没法和蓝图配合。
GIF