FindAllOf

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 许可