【UE4】引擎配置文件原理学习笔记
创始人
2024-03-29 08:23:46
0

刚好遇到一个ini加载的优化。趁此机会记录学习一下UE引擎的config文件层级结构和读取流程

文章目录

  • 两个问题
  • 层级结构
  • 文件读取流程
    • 初始化流程
    • 文件读取流程
    • 文件的写入
  • 配置文件内容和GConfig结构

两个问题

在看项目目录结构的时候,有没有这样的疑问:
为什么saved同级目录下面有一个config,saved里面还有一个config:saved/config?它们有什么区别吗?
在这里插入图片描述

看虚幻读配置文件的源码:发现它读取配置文件用的是一个LoadExternalIniFile的函数。但这个函数执行了读操作以外,还进行了写操作。为什么虚幻加载配置文件的以后还要写文件?
在这里插入图片描述

层级结构

实际上,UE采用的config配置文件读取策略是以层级的形式,可以分为以下四个层级:

  1. Engine/Config
  2. Engine/Saved/Config
  3. [ProjectName]/Config
  4. [ProjectName]/Saved/Config

加载一个名为"ConfigFileName"的config文件的时候,UE会依次遍历这些目录。后读取的覆盖前面的,即:其优先级依次递增。

这个层级的概念很有意思。颇有点子类复写的味道:如果项目内的目录就有ConofigFileName这个ini,就使用项目内的ini。否则使用其父层级引擎目录的ConofigFileName.ini。

保证了修改一个项目的ini不会影响到别的项目,没修改的部分依然沿用通用的设置。

UE会读到的配置文件目录记录于ConfigCacheIni.cpp的GConfigLayers中:

// ConfigCacheIni.cpp
GConfigLayers[] =
{/****************************************************** CRITICAL NOTES**** If you change this array, you need to also change EnumerateConfigFileLocations() in ConfigHierarchy.cs!!!**** And maybe UObject::GetDefaultConfigFilename(), UObject::GetGlobalUserConfigFilename()**************************************************/// Engine/Base.ini{ TEXT("AbsoluteBase"),				TEXT("{ENGINE}/Config/Base.ini"), EConfigLayerFlags::Required | EConfigLayerFlags::NoExpand},// Engine/Base*.ini{ TEXT("Base"),						TEXT("{ENGINE}/Config/Base{TYPE}.ini") },// Engine/Platform/BasePlatform*.ini{ TEXT("BasePlatform"),				TEXT("{ENGINE}/Config/{PLATFORM}/Base{PLATFORM}{TYPE}.ini")  },// Project/Default*.ini{ TEXT("ProjectDefault"),			TEXT("{PROJECT}/Config/Default{TYPE}.ini"), EConfigLayerFlags::AllowCommandLineOverride | EConfigLayerFlags::GenerateCacheKey },// Project/Generated*.ini Reserved for files generated by build process and should never be checked in { TEXT("ProjectGenerated"),			TEXT("{PROJECT}/Config/Generated{TYPE}.ini"), EConfigLayerFlags::GenerateCacheKey },// Engine/Platform/Platform*.ini{ TEXT("EnginePlatform"),			TEXT("{ENGINE}/Config/{PLATFORM}/{PLATFORM}{TYPE}.ini") },// Project/Platform/Platform*.ini{ TEXT("ProjectPlatform"),			TEXT("{PROJECT}/Config/{PLATFORM}/{PLATFORM}{TYPE}.ini") },// Project/Generated*.ini Reserved for files generated by build process and should never be checked in { TEXT("ProjectPlatformGenerated"),	TEXT("{PROJECT}/Config/{PLATFORM}/Generated{PLATFORM}{TYPE}.ini") },// UserSettings/.../User*.ini{ TEXT("UserSettingsDir"),			TEXT("{USERSETTINGS}Unreal Engine/Engine/Config/User{TYPE}.ini"), EConfigLayerFlags::NoExpand },// UserDir/.../User*.ini{ TEXT("UserDir"),					TEXT("{USER}Unreal Engine/Engine/Config/User{TYPE}.ini"), EConfigLayerFlags::NoExpand },// Project/User*.ini{ TEXT("GameDirUser"),				TEXT("{PROJECT}/Config/User{TYPE}.ini"), EConfigLayerFlags::GenerateCacheKey | EConfigLayerFlags::NoExpand },
};

文件读取流程

初始化流程

读进来的ini配置文件都被缓存在全局变量GConfig里。
在这里插入图片描述

文件读取流程

在这里插入图片描述
其中主要的耗时在读配置和写配置这两个位置。

文件的写入

UE在进行了上述的层级遍历以后,会得到一份最后生效的配置文件。它将这个文件的内容写入Saved目录中。

只从Engine/Config中读取,子层级没有复写的文件,写入Engine/Saved/Config中。否则写入[ProjectName]/Saved/Config中。注意这边的写入只写有差异的部分。

对于某个property的写入,如果这个property的值与其class的CDO相同,则没有存储多份的必要,不会写入配置文件。

为了遍历以确保不存储多份相同信息,写操作内涵多个嵌套的for遍历。如果ini文件非常大,ConfigFile.Write这个操作可能会花费非常多的时间。

所以我们的第一个问题就解决了:带Saved的路径下文件是运行时写入的,不带Save的是原有配置,用于读取的。

  1. Engine/Config【原有配置】
  2. Engine/Saved/Config【引擎运行后写入】
  3. [ProjectName]/Config【原有配置】
  4. [ProjectName]/Saved/Config【项目运行后写入】

这里有一个疑问:为什么在初始化加载ini文件的时候还需要写入到saved?虽然UE在写入的操作内部进行了比较,如果跟自己父层级的内容没有不一样的地方,就不写入saved目录下。但初始化加载的时候理论上刚刚加载到GConfig的内容是不会被修改的

配置文件内容和GConfig结构

打开一个配置文件可以看到其结构:
在这里插入图片描述
抽象出来一个ConfigFile的文件结构如下:
在这里插入图片描述
GConfig也是完全按照这个结构来构造的:
在这里插入图片描述
GConfig是一个以文件名作为key值的TMap;FConfigFile是一个以Section名作为Key的TMap,而FConfigSection则是每个Section下面的键值对。

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...