如何根据名称从数组中删除特定子元素

我正在创建一种obby,对于其中一个级别,我计划制作一个平台,当踏上该平台时,基于我为平台设置的这些"检查点"的位置,平台会改变位置。我在Explorer中有一个名为"Levels"的文件夹,文件夹中有级别,并且我已经添加了所有构建级别所需的部件,附加到一个父部件上。我使用:GetChildren()函数将所有子元素添加到级别的父部件中的一个数组中,现在我正在尝试排序和删除任何不是检查点的部件。所有检查点都称为Tele1、Tele2、Tele3等...目前我正在使用Table.remove,但我听说它很糟糕,永远不应该使用,但我也是一名新手,所以不知道该如何处理。这是我的代码:

local checkpoints = game.Workspace.Levels.Level3:GetChildren()

for i, v in pairs(checkpoints) do
    if string.match(v.Name, "Tele") then

    else
        table.remove(checkpoints, i)
    end

    print(i, v)
end

打印以查看表是否已正确排序。

点赞
用户9922866
用户9922866

首先,作为一个旁注,我建议把等级文件夹存储在 ServerScriptStorage 而不是 game.Workspace 里。下面的例子基于这个前提。

你可以通过迭代 GetChildren() 获得的表格来更轻松地抓取你认为是检查点的所有游戏部分,例如:

-- 对 string 匹配提供的含有锚点的 pattern:它包含了一个字符串的开头和结尾,并且搜寻 'Tele' 后跟
-- 一个或多个数字。它应该被视为一个常量,因此使用大写字母。
local CHECKPOINT_PATTERN = "^Tele%d+$"

local serverStorage = game:GetService("ServerStorage")
local levels = serverStorage:FindFirstChild("Levels")
local level3 = levels:FindFirstChild("Level3")

-- 检查特定部分是否是检查点的辅助函数。
-- 要求:部分是 BasePart。
-- 效果:如果 part.Name 匹配 CHECKPOINT_PATTERN,则返回 true,否则返回 false。
local function is_checkpoint(part)
    return part.Name:match(CHECKPOINT_PATTERN) ~= nil
end

-- 获得 Level3 的子代,它应该包含 x 个检查点。
local children = level3:GetChildren()

-- 创建一个新的表格,在其中插入您认为是检查点的所有游戏部分。
local checkpoints = {}

-- 通过迭代表格 children 来查找检查点。
for _, child in ipairs(children) do
    if (is_checkpoint(child)) then
        table.insert(checkpoints, child)
    end
end

-- 为了进一步抽象这个过程,上面的 for 循环可以放在一个函数中,该函数返回检查点的表格;不过,这完全取决于你和你如何设置你的代码之间的余地。

-- 继续使用代码,现在 Level3 中的所有检查点都已被定位并插入到表格 checkpoints 中。

这比修改 game.Workspace.Levels.Level3:GetChildren() 生成的原始表格要简单得多。

作为一种替代方案,更高级的解决方案取决于您如何准确地设置您的场所,您可以使用 CollectionService 标记您认为是检查点的所有游戏部分;然后,您可以通过调用 CollectionService:GetTagged(<tag>) 获取包含这些检查点的表格。有关参考,请参阅 Roblox Wiki 上的这个页面。

澄清编辑:

我把称为 CHECKPOINT_PATTERN 的变量(我把它作为一个常量处理)作为一个字符串模式;我在与你的 string.match(v.Name, "Tele") 相同的角色中使用它,尽管我的版本略有不同。解释一下:字符 ^$ 被称为锚点--前者意味着模式匹配应该从字符串的前面开始,后者则做同样的事情,但表示结束; “Tele” 跟你原来的代码一样;而 "%d+" 匹配一个或多个数字。有关 Lua 中字符串模式的更多信息,请参见这个页面。

至于将 Levels 文件夹放在 ServerStorage 中的问题,这是一个好主意,因为它更好地组织了一个位置的资产;而且,它比将东西存储在例如 game.Lighting 中更安全。我建议这是基于良好实践,但它当然取决于你的场所是如何设置的 - 如果这样做会删除你整个 Obby,那么需要重组你的场所和代码来使其工作。

2020-09-21 17:01:02