当前位置: 首页 > article >正文

UE学习日志#11GAS--ASC源码简要分析9 AbilitySystemGlobals分析2 初始化相关

1 static UAbilitySystemGlobals& Get()

保证了是单例,IGameplayAbilitiesModule继承了IModuleInterface

	/** Gets the single instance of the globals object, will create it as necessary */
	static UAbilitySystemGlobals& Get()
	{
		return *IGameplayAbilitiesModule::Get().GetAbilitySystemGlobals();
	}

2 InitGlobalData相关

2.1 InitGlobalData

确保不会再次初始化

获取一些列初值

绑定到指定回调

void UAbilitySystemGlobals::InitGlobalData()
{
	// Make sure the user didn't try to initialize the system again (we call InitGlobalData automatically in UE5.3+).
	if (IsAbilitySystemGlobalsInitialized())
	{
		return;
	}
	bInitialized = true;

	LLM_SCOPE(TEXT("AbilitySystem"));
	GetGlobalCurveTable();
	GetGlobalAttributeMetaDataTable();
	
	InitAttributeDefaults();
	ReloadAttributeDefaults();

	GetGameplayCueManager();
	GetGameplayTagResponseTable();
	InitGlobalTags();
	PerformDeveloperSettingsUpgrade();

	InitTargetDataScriptStructCache();

	// Register for PreloadMap so cleanup can occur on map transitions
	FCoreUObjectDelegates::PreLoadMapWithContext.AddUObject(this, &UAbilitySystemGlobals::HandlePreLoadMap);

#if WITH_EDITOR
	// Register in editor for PreBeginPlay so cleanup can occur when we start a PIE session
	if (GIsEditor)
	{
		FEditorDelegates::PreBeginPIE.AddUObject(this, &UAbilitySystemGlobals::OnPreBeginPIE);
	}
#endif
}

2.2 IsAbilitySystemGlobalsInitialized

朴实无华返回bInitialized

bool UAbilitySystemGlobals::IsAbilitySystemGlobalsInitialized() const
{
	return bInitialized;
}

2.3 GetGlobalCurveTable和GetGlobalAttributeMetaDataTable

从UGameplayAbilitiesDeveloperSettings中获取GlobalCurveTableName然后TryLoad

UCurveTable * UAbilitySystemGlobals::GetGlobalCurveTable()
{
	if (!GlobalCurveTable)
	{
		const UGameplayAbilitiesDeveloperSettings* DeveloperSettings = GetDefault<UGameplayAbilitiesDeveloperSettings>();
		if (DeveloperSettings->GlobalCurveTableName.IsValid())
		{
			GlobalCurveTable = Cast<UCurveTable>(DeveloperSettings->GlobalCurveTableName.TryLoad());
		}
	}
	return GlobalCurveTable;
}

 GetGlobalAttributeMetaDataTable同理

UDataTable * UAbilitySystemGlobals::GetGlobalAttributeMetaDataTable()
{	
	if (!GlobalAttributeMetaDataTable)
	{
		const UGameplayAbilitiesDeveloperSettings* DeveloperSettings = GetDefault<UGameplayAbilitiesDeveloperSettings>();
		if (DeveloperSettings->GlobalAttributeMetaDataTableName.IsValid())
		{
			GlobalAttributeMetaDataTable = Cast<UDataTable>(DeveloperSettings->GlobalAttributeMetaDataTableName.TryLoad());
		}
	}
	return GlobalAttributeMetaDataTable;
}

2.4 InitAttributeDefaults/GetGlobalAttributeSetDefaultsTablePaths

2.4.1 InitAttributeDefaults

先获取AttributeSetDefaultsTable的路径软引用

然后依次遍历路径,尝试Load,TryLoad是同步加载,可能会阻塞,常用于小资源加载

void UAbilitySystemGlobals::InitAttributeDefaults()
{
	TArray<FSoftObjectPath> AttribSetDefaultsTables = GetGlobalAttributeSetDefaultsTablePaths();
	for (const FSoftObjectPath& AttribSetDefaultsTablePath : AttribSetDefaultsTables)
	{
		if (AttribSetDefaultsTablePath.IsValid())
		{
			UCurveTable* AttribTable = Cast<UCurveTable>(AttribSetDefaultsTablePath.TryLoad());
			if (ensureMsgf(AttribTable, TEXT("Could not load Global AttributeSet Defaults Table: %s"), *AttribSetDefaultsTablePath.ToString()))
			{
				GlobalAttributeDefaultsTables.AddUnique(AttribTable);
			}
		}
	}
}

2.4.2 GetGlobalAttributeSetDefaultsTablePaths

PRAGMA_DISABLE/ENABLE_DEPRECATION_WARNINGS关闭和开启警告,中间的部分弃用,单个的全局tablename,保留以兼容

之后还是通过UGameplayAbilitiesDeveloperSettings获取

TArray<FSoftObjectPath> UAbilitySystemGlobals::GetGlobalAttributeSetDefaultsTablePaths() const
{
	TArray<FSoftObjectPath> AttribSetDefaultsTables;

PRAGMA_DISABLE_DEPRECATION_WARNINGS
	// Handle deprecated, single global table name
	if (GlobalAttributeSetDefaultsTableName.IsValid())
	{
		AttribSetDefaultsTables.Add(GlobalAttributeSetDefaultsTableName);
	}
	PRAGMA_ENABLE_DEPRECATION_WARNINGS

	const UGameplayAbilitiesDeveloperSettings* DeveloperSettings = GetDefault<UGameplayAbilitiesDeveloperSettings>();
	AttribSetDefaultsTables.Append(DeveloperSettings->GlobalAttributeSetDefaultsTableNames);

	return AttribSetDefaultsTables;
}

 2.5 ReloadAttributeDefaults

重新加载GlobalAttributeDefaultsTables

如果在编辑器模式下,注册重新加载的回调

一个布尔变量确保只注册过一次

void UAbilitySystemGlobals::ReloadAttributeDefaults()
{
	if (!GlobalAttributeDefaultsTables.IsEmpty())
	{
		AllocAttributeSetInitter();
		GetAttributeSetInitter()->PreloadAttributeSetData(GlobalAttributeDefaultsTables);

		// Subscribe for reimports if in the editor
#if WITH_EDITOR
		if (GIsEditor && !RegisteredReimportCallback)
		{
			GEditor->GetEditorSubsystem<UImportSubsystem>()->OnAssetReimport.AddUObject(this, &UAbilitySystemGlobals::OnTableReimported);
			RegisteredReimportCallback = true;
		}
#endif
	}
}

2.6 GetGameplayCueManager

通过DeveloperSettings的Name或者Class来创建GlobalGameplayCueManager

回调OnCreated

判断是否要在Start加载ObjectLibraries

UGameplayCueManager* UAbilitySystemGlobals::GetGameplayCueManager()
{
	if (GlobalGameplayCueManager == nullptr)
	{
		const UGameplayAbilitiesDeveloperSettings* DeveloperSettings = GetDefault<UGameplayAbilitiesDeveloperSettings>();
		// Loads mud specific gameplaycue manager object if specified
		if (GlobalGameplayCueManager == nullptr && DeveloperSettings->GlobalGameplayCueManagerName.IsValid())
		{
			GlobalGameplayCueManager = LoadObject<UGameplayCueManager>(nullptr, *DeveloperSettings->GlobalGameplayCueManagerName.ToString(), nullptr, LOAD_None, nullptr);
			if (GlobalGameplayCueManager == nullptr)
			{
				ABILITY_LOG(Error, TEXT("Unable to Load GameplayCueManager %s"), *DeveloperSettings->GlobalGameplayCueManagerName.ToString() );
			}
		}
		
		// Load specific gameplaycue manager class if specified
		if ( GlobalGameplayCueManager == nullptr && DeveloperSettings->GlobalGameplayCueManagerClass.IsValid() )
		{
			UClass* GCMClass = LoadClass<UObject>(nullptr, *DeveloperSettings->GlobalGameplayCueManagerClass.ToString(), nullptr, LOAD_None, nullptr);
			if (GCMClass)
			{
				GlobalGameplayCueManager = NewObject<UGameplayCueManager>(this, GCMClass, NAME_None);
			}
		}
		
		if ( GlobalGameplayCueManager == nullptr)
		{
			// Fallback to base native class
			GlobalGameplayCueManager = NewObject<UGameplayCueManager>(this, UGameplayCueManager::StaticClass(), NAME_None);
		}

		GlobalGameplayCueManager->OnCreated();

		if (GetGameplayCueNotifyPaths().IsEmpty())
		{
			AddGameplayCueNotifyPath(TEXT("/Game"));
			ABILITY_LOG(Warning, TEXT("No GameplayCueNotifyPaths were specified in DefaultGame.ini under [/Script/GameplayAbilities.AbilitySystemGlobals]. Falling back to using all of /Game/. This may be slow on large projects. Consider specifying which paths are to be searched."));
		}
		
		if (GlobalGameplayCueManager->ShouldAsyncLoadObjectLibrariesAtStart())
		{
			StartAsyncLoadingObjectLibraries();
		}
	}

	check(GlobalGameplayCueManager);
	return GlobalGameplayCueManager;
}

2.7 GetGameplayTagResponseTable

还是从DeveloperSettings里获取

UGameplayTagReponseTable* UAbilitySystemGlobals::GetGameplayTagResponseTable()
{
	const UGameplayAbilitiesDeveloperSettings* DeveloperSettings = GetDefault<UGameplayAbilitiesDeveloperSettings>();
	if (GameplayTagResponseTable == nullptr && DeveloperSettings->GameplayTagResponseTableName.IsValid())
	{
		GameplayTagResponseTable = LoadObject<UGameplayTagReponseTable>(nullptr, *DeveloperSettings->GameplayTagResponseTableName.ToString(), nullptr, LOAD_None, nullptr);
	}

	return GameplayTagResponseTable;
}

2.8 InitGlobalTags

 标记激活失败的原因的标签

void UAbilitySystemGlobals::InitGlobalTags()
{
	auto TagFromDeprecatedName = [](FGameplayTag& Tag, FName DeprecatedName)
	{
		if (!Tag.IsValid() && !DeprecatedName.IsNone())
		{
			Tag = FGameplayTag::RequestGameplayTag(DeprecatedName);
			return true;
		}

		return false;
	};

PRAGMA_DISABLE_DEPRECATION_WARNINGS
	TagFromDeprecatedName(ActivateFailIsDeadTag, ActivateFailIsDeadName);
	TagFromDeprecatedName(ActivateFailCooldownTag, ActivateFailCooldownName);
	TagFromDeprecatedName(ActivateFailCostTag, ActivateFailCostName);
	TagFromDeprecatedName(ActivateFailTagsBlockedTag, ActivateFailTagsBlockedName);
	TagFromDeprecatedName(ActivateFailTagsMissingTag, ActivateFailTagsMissingName);
	TagFromDeprecatedName(ActivateFailNetworkingTag, ActivateFailNetworkingName);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
}

2.9 PerformDeveloperSettingsUpgrade

先定义一个lambda表达式用于同步标签

检查是否需要更新

若需要更新就把Settings里的标签同步到Globals里

void UAbilitySystemGlobals::PerformDeveloperSettingsUpgrade()
{
	auto SyncTag = [](FGameplayTag& DestinationTag, const FGameplayTag& OurTag)
	{
		if (OurTag.IsValid() && DestinationTag != OurTag)
		{
			DestinationTag = OurTag;
			return true;
		}

		return false;
	};

	UGameplayAbilitiesDeveloperSettings* DeveloperSettings = GetMutableDefault<UGameplayAbilitiesDeveloperSettings>();

	bool bUpgraded = false;
	bUpgraded |= SyncTag(DeveloperSettings->ActivateFailCooldownTag, ActivateFailCooldownTag);
	bUpgraded |= SyncTag(DeveloperSettings->ActivateFailCostTag, ActivateFailCostTag);
	bUpgraded |= SyncTag(DeveloperSettings->ActivateFailNetworkingTag, ActivateFailNetworkingTag);
	bUpgraded |= SyncTag(DeveloperSettings->ActivateFailTagsBlockedTag, ActivateFailTagsBlockedTag);
	bUpgraded |= SyncTag(DeveloperSettings->ActivateFailTagsMissingTag, ActivateFailTagsMissingTag);

	if (bUpgraded)
	{
		UE_LOG(LogAbilitySystem, Warning, TEXT("AbilitySystemGlobals' Tags did not agree with GameplayAbilitiesDeveloperSettings.  Updating GameplayAbilitiesDeveloperSettings Config to use Tags from AbilitySystemGlobals"));

		bool bSuccess = DeveloperSettings->TryUpdateDefaultConfigFile();
		if (!bSuccess)
		{
			UE_LOG(LogAbilitySystem, Warning, TEXT("AbilitySystemGlobals config file (DefaultGame.ini) couldn't be saved. Make sure the file is writable to update it."));
		}
	}

	// Now that the upgrade is done, copy any settings set in the DeveloperSettings back to here (so calls to UAbilitySystemGlobals::Get().SomeTag work)
	SyncTag(ActivateFailCooldownTag, DeveloperSettings->ActivateFailCooldownTag);
	SyncTag(ActivateFailCostTag, DeveloperSettings->ActivateFailCostTag);
	SyncTag(ActivateFailNetworkingTag, DeveloperSettings->ActivateFailNetworkingTag);
	SyncTag(ActivateFailTagsBlockedTag, DeveloperSettings->ActivateFailTagsBlockedTag);
	SyncTag(ActivateFailTagsMissingTag, DeveloperSettings->ActivateFailTagsMissingTag);
}

2.10 InitTargetDataScriptStructCache

这个暂时还不太清楚作用,暂放一下

void UAbilitySystemGlobals::InitTargetDataScriptStructCache()
{
	TargetDataStructCache.InitForType(FGameplayAbilityTargetData::StaticStruct());
	EffectContextStructCache.InitForType(FGameplayEffectContext::StaticStruct());
}


http://www.kler.cn/a/520638.html

相关文章:

  • /opt安装软件,就可以使用man xx命令是为什么
  • unity.NavMesh Agent
  • ES设置证书和创建用户,kibana连接es
  • 计算机网络之链路层
  • 动态规划一> 让字符串成为回文串的最少插入次数
  • 在 Windows 11 中为 SMB 3.x 文件共享协议提供 RDMA 支持
  • Chapter 3-17. Detecting Congestion in Fibre Channel Fabrics
  • Java多线程与高并发专题——保障原子性
  • 【FreeRTOS 教程 五】FreeRTOS 内存管理细致讲解
  • easyexcel-导入(读取)(read)-示例及核心部件
  • 记录让cursor帮我给ruoyi-vue后台管理项目整合mybatis-plus
  • 第05章 04 VTK标量算法概述
  • 【时时三省】(C语言基础)对比一组函数
  • 如何使用 OpenSSL 检查 Linux 中的 SSL 证书
  • 解决查看服务器ESN(许可证管理)
  • HarmonyOS:MVVM模式
  • 一文大白话讲清楚webpack基本使用——16——图片压缩
  • vscode无法格式化go代码的问题
  • 第24篇:Python开发进阶:掌握Python编程中的调试技巧
  • 【Leetcode 每日一题】40. 组合总和 II
  • 股指期货的交易规则及细节详解
  • web前端4--css盒模型
  • 渗透测试技法之口令安全
  • Day35:字符串的大小写转换
  • MFC常用操作
  • vue 返回页面时刷新