FindAllOf
FindAllOf 函数查找指定类名的所有非默认实例。
此函数无法查找非实例对象或默认实例。
参数
| # | 类型 | 说明 |
|---|---|---|
| 1 | string | 要查找其实例的类的短名称 |
返回值
| # | 类型 | 子类型 | 说明 |
|---|---|---|---|
| 1 | nil or table | UObject, UClass, or AActor | 找不到实例时返回 nil;否则返回以数字为索引、包含全部实例的表 |
示例
输出所有继承自 Actor 类的对象的名称。
local ActorInstances = FindAllOf("Actor")
if not ActorInstances then
print("No instances of 'Actor' were found\n")
else
for Index, ActorInstance in pairs(ActorInstances) do
print(string.format("[%d] %s\n", Index, ActorInstance:GetFullName()))
end
end
性能
此函数必须完整遍历整个全局对象数组,因此速度很慢。
应尽可能避免在正式使用的代码中调用此函数。
如果必须使用,可以通过 # 运算符检查找到的对象数量。
如果对象很多,应考虑减少遍历这些对象时执行的工作量。
优先手动遍历 outer、class 和/或 super 链,对链上的每个元素调用 UObject::GetFName,避免调用 UObject::GetFullName 后再处理字符串。
可以在循环外缓存用于比较的 FName。
也可以改为调用 UObject::IsA。
下面的示例查找全部 Actor,再通过筛选仅对 Light 实例执行逻辑。
此示例刻意写得较复杂,用于展示如何遍历父结构体链表。
local AllActors = FindAllOf("Actor")
print(string.format("NumActors found: %s\n", #AllActors))
local LightName = UEHelpers.FindOrAddFName("Light")
for _, Actor in ipairs(AllActors) do
-- Filter on the type.
-- The class represents the type.
local ActorClass = Actor:GetClass()
-- Check direct type.
local bIsLight = false
if ActorClass:GetFName() == LightName then
-- Is directly a Light.
bIsLight = true
end
-- Check inheritance.
local Super = ActorClass:GetSuperStruct()
while Super:IsValid() do
if Super:GetFName() == LightName then
-- Inherits from Light.
bIsLight = true
end
Super = Super:GetSuperStruct()
end
if bIsLight then
-- Do logic on Light.
end
end
向 FindAllOf 指定更具体的类型,通常就能让函数直接完成这种筛选。
例如,上面的整个示例可以直接用一次 FindAllOf("Light") 调用替代。
下面是另一个更实用的示例:获取全部灯光,并根据灯光的具体类型执行相应操作:
local function IsObjectOfType(Object, TypeName)
-- Filter on the type.
-- The class represents the type.
local ObjectClass = Object:GetClass()
-- Check direct type.
if ObjectClass:GetFName() == TypeName then
return true
end
-- Check inheritance.
local Super = ObjectClass:GetSuperStruct()
while Super:IsValid() do
if Super:GetFName() == TypeName then
return true
end
Super = Super:GetSuperStruct()
end
return false
end
local AllActors = FindAllOf("Light")
print(string.format("NumActors found: %s\n", #AllActors))
local PointLightName = UEHelpers.FindOrAddFName("PointLight")
local RectLightName = UEHelpers.FindOrAddFName("RectLight")
local SpotLightName = UEHelpers.FindOrAddFName("SpotLight")
local DirectionalLightName = UEHelpers.FindOrAddFName("DirectionalLight")
for _, Light in ipairs(AllActors) do
if IsObjectOfType(Light, PointLightName) then
-- Do logic on PointLight.
end
if IsObjectOfType(Light, RectLightName) then
-- Do logic on RectLight.
end
if IsObjectOfType(Light, SpotLightName) then
-- Do logic on SpotLight.
end
if IsObjectOfType(Light, DirectionalLightName) then
-- Do logic on DirectionalLightName.
end
end
如果不想自己编写筛选逻辑,也可以使用辅助函数 IsA。
IsA 函数会进行完整的类型检查,使用的是类对象而不是名称,因此需要
自行缓存并传入这些类对象。
这是验证类型最准确的方式。
local AllActors = FindAllOf("Light")
print(string.format("NumActors found: %s\n", #AllActors))
local PointLightClass = StaticFindObject("/Script/Engine.PointLight")
local RectLightClass = StaticFindObject("/Script/Engine.RectLight")
local SpotLightClass = StaticFindObject("/Script/Engine.SpotLight")
local DirectionalLightClass = StaticFindObject("/Script/Engine.DirectionalLight")
for _, Actor in ipairs(AllActors) do
if Actor:IsA(PointLightClass) then
-- Do logic on PointLight.
print(string.format("PL: '%s'\n", Actor:GetFullName()))
end
if Actor:IsA(RectLightClass) then
-- Do logic on RectLight.
print(string.format("RL: '%s'\n", Actor:GetFullName()))
end
if Actor:IsA(SpotLightClass) then
-- Do logic on SpotLight.
print(string.format("SL: '%s'\n", Actor:GetFullName()))
end
if Actor:IsA(DirectionalLightClass) then
-- Do logic on DirectionalLightName.
print(string.format("DL: '%s'\n", Actor:GetFullName()))
end
end
原文:docs/lua-api/global-functions/findallof.md · 固定提交 560411f18512 · 来源与 MIT 许可