控制台变量(ConsoleVariable)基础
在 Output Log 面板下方,或者按下`之后的输入框中,可以输入控制台命令。
常用的控制台命令除了包括 控制台变量 还包括 “Stat命令” 等。
完整的控制台命令可以查阅 UE4 Console Variables and Commands
对于控制台变量,输入变量名后跟?
可以查阅当前的值以及是通过什么方式设置的(什么都不跟则只显示当前值):
Cmd: r.Streaming.PoolSize ?
HELP for 'r.Streaming.PoolSize':
-1: Default texture pool size, otherwise the size in MB
r.Streaming.PoolSize = "1000" LastSetBy: Scalability
如果输入变量名后跟一个具体的值,则就会改变。输入后再查询它可看到:
Cmd: r.Streaming.PoolSize 1200
r.Streaming.PoolSize = "1200"
LogContentStreaming: Texture pool size now 1200 MB
Cmd: r.Streaming.PoolSize ?
HELP for 'r.Streaming.PoolSize':
-1: Default texture pool size, otherwise the size in MB
r.Streaming.PoolSize = "1200" LastSetBy: Console
控制台变量的设置优先级
从代码注释可以看到控制台变量各种设置方式的优先级(更详细的观察过程见附录):
名字 | 注释 | 翻译 |
---|---|---|
Constructor | lowest priority (default after console variable creation) | 最低优先级(控制台变量创建后的默认值) |
Scalability | from Scalability.ini (lower priority than game settings so it’s easier to override partially) | 来自 Scalability.ini 的可延展性(优先级低于GameSetting,因此更容易被部分覆盖) |
GameSetting | (in game UI or from file) | 在游戏UI中设置,或者来自文件 |
ProjectSetting | project settings (editor UI or from file, higher priority than game setting to allow to enforce some setting fro this project) | 项目设置(编辑器 UI 或来自文件,比GameSetting优先级更高以允许强制执行此项目的某些设置) |
SystemSettingsIni | per project setting (ini file e.g. Engine.ini or Game.ini) | 每个项目的设置(ini 文件,例如 Engine.ini 或 Game.ini) |
DeviceProfile | per device setting (e.g. specific iOS device, higher priority than per project to do device specific settings) | 每个设备的 DeviceProfile 设置(例如特定的 iOS 设备,优先级比项目的更高,因此可以进行设备特定的设置) |
ConsoleVariablesIni | consolevariables.ini (for multiple projects) | consolevariables.ini(用于多个项目) |
Commandline | a minus command e.g. -VSync (very high priority to enforce the setting for the application) | 减号命令,例如 -VSync(非常高的优先级以强制应用程序设置) |
Code | least useful, likely a hack, maybe better to find the correct SetBy… | 最不常使用的,可能用于某些hack,最好以更正确的方式来设置… |
Console | editor UI or console in game or editor | 编辑器UI或者游戏或编辑器中的控制台 |
实验
以r.Streaming.PoolSize
为例:
Scalability
Cmd: r.Streaming.PoolSize ?
HELP for 'r.Streaming.PoolSize':
-1: Default texture pool size, otherwise the size in MB
r.Streaming.PoolSize = "1000" LastSetBy: Scalability
可以看到,它现在被Scalability所设置。
Scalability相关的配置可在 UE_4.27\Engine\Config\BaseScalability.ini 中看到。比如r.Streaming.PoolSize
可以找到:
假如修改画质,将可以看到值被改变
Device Profiles
根据优先级的讨论可以知道,Device Profiles 有更高的优先级。
更改 \UE_4.27\Engine\Config\BaseDeviceProfiles.ini 中的Windows添加r.Streaming.PoolSize
的设置:
现在,打开引擎后查询r.Streaming.PoolSize
后可以看到:
Cmd: r.Streaming.PoolSize ?
HELP for 'r.Streaming.PoolSize':
-1: Default texture pool size, otherwise the size in MB
r.Streaming.PoolSize = "1600" LastSetBy: DeviceProfile
可以看到值确实被覆盖了。
(另外,此部分也可以在引擎中使用界面来观察:)
附录:观察代码中控制台变量的设置优先级
注意到控制台输出的LastSetBy表示被设置的方式。因此搜索此字符串后,找到:
在 \Engine\Source\Runtime\Core\Private\HAL\ConsoleManager.cpp 中:
Ar.Logf(TEXT("%s = \"%s\" LastSetBy: %s"), *Param1, *CVar->GetString(), GetSetByTCHAR(CVar->GetFlags()));
其中:
CVar
类型是IConsoleVariable
,它的成员GetFlags()
返回枚举EConsoleVariableFlags
:
enum EConsoleVariableFlags
{
/* Mask for flags. Use this instead of ~ECVF_SetByMask */
ECVF_FlagMask = 0x0000ffff,
/**
* Default, no flags are set, the value is set by the constructor
*/
ECVF_Default = 0x0,
/**
* Console variables marked with this flag behave differently in a final release build.
* Then they are are hidden in the console and cannot be changed by the user.
*/
ECVF_Cheat = 0x1,
/**
* Console variables cannot be changed by the user (from console).
* Changing from C++ or ini is still possible.
*/
ECVF_ReadOnly = 0x4,
/**
* UnregisterConsoleObject() was called on this one.
* If the variable is registered again with the same type this object is reactivated. This is good for DLL unloading.
*/
ECVF_Unregistered = 0x8,
/**
* This flag is set by the ini loading code when the variable wasn't registered yet.
* Once the variable is registered later the value is copied over and the variable is destructed.
*/
ECVF_CreatedFromIni = 0x10,
/**
* Maintains another shadow copy and updates the copy with render thread commands to maintain proper ordering.
* Could be extended for more/other thread.
* Note: On console variable references it assumes the reference is accessed on the render thread only
* (Don't use in any other thread or better don't use references to avoid the potential pitfall).
*/
ECVF_RenderThreadSafe = 0x20,
/* ApplyCVarSettingsGroupFromIni will complain if this wasn't set, should not be combined with ECVF_Cheat */
ECVF_Scalability = 0x40,
/* those cvars control other cvars with the flag ECVF_Scalability, names should start with "sg." */
ECVF_ScalabilityGroup = 0x80,
// ------------------------------------------------
/* Set flags */
ECVF_SetFlagMask = 0x00ff0000,
// Use to set a cvar without calling all cvar sinks. Much faster, but potentially unsafe. Use only if you know the particular cvar/setting does not require a sink call
ECVF_Set_NoSinkCall_Unsafe = 0x00010000,
// ------------------------------------------------
/* to get some history of where the last value was set by ( useful for track down why a cvar is in a specific state */
ECVF_SetByMask = 0xff000000,
// the ECVF_SetBy are sorted in override order (weak to strong), the value is not serialized, it only affects it's override behavior when calling Set()
// lowest priority (default after console variable creation)
ECVF_SetByConstructor = 0x00000000,
// from Scalability.ini (lower priority than game settings so it's easier to override partially)
ECVF_SetByScalability = 0x01000000,
// (in game UI or from file)
ECVF_SetByGameSetting = 0x02000000,
// project settings (editor UI or from file, higher priority than game setting to allow to enforce some setting fro this project)
ECVF_SetByProjectSetting = 0x03000000,
// per project setting (ini file e.g. Engine.ini or Game.ini)
ECVF_SetBySystemSettingsIni = 0x04000000,
// per device setting (e.g. specific iOS device, higher priority than per project to do device specific settings)
ECVF_SetByDeviceProfile = 0x05000000,
// consolevariables.ini (for multiple projects)
ECVF_SetByConsoleVariablesIni = 0x06000000,
// a minus command e.g. -VSync (very high priority to enforce the setting for the application)
ECVF_SetByCommandline = 0x07000000,
// least useful, likely a hack, maybe better to find the correct SetBy...
ECVF_SetByCode = 0x08000000,
// editor UI or console in game or editor
ECVF_SetByConsole = 0x09000000,
// ------------------------------------------------
};
而GetSetByTCHAR
将上面特定枚举值转换为字符串:
// Get human readable string
// @return never 0
static const TCHAR* GetSetByTCHAR(EConsoleVariableFlags InSetBy)
{
EConsoleVariableFlags SetBy = (EConsoleVariableFlags)((uint32)InSetBy & ECVF_SetByMask);
switch(SetBy)
{
#define CASE(A) case ECVF_SetBy##A: return TEXT(#A);
// Could also be done with enum reflection instead
CASE(Constructor)
CASE(Scalability)
CASE(GameSetting)
CASE(ProjectSetting)
CASE(DeviceProfile)
CASE(SystemSettingsIni)
CASE(ConsoleVariablesIni)
CASE(Commandline)
CASE(Code)
CASE(Console)
#undef CASE
}
return TEXT("<UNKNOWN>");
}