如何使脚本影响 Roblox LUA 中的所有子项?

我是 LUA 编程的新手,尽管我学过类似于 JS 的语言。如果我必须在组中的许多部分中更改相同的脚本,并用每个脚本替换它们,这很令人沮丧,我不知道一种优雅的方法来做到这一点。相反,我决定将所有部件嵌套在脚本中。我看过一些例子,试图适应其中的一些,但它们并不完全适用于我想要做的事情,我也无法让它们工作。

本质上,我想做的是监视所有砖块,以便玩家可以与它们联系。我拿取了最初隐藏的砖块脚本,并进行了修改。如果触摸了某个部件(砖块),那么应该调用 onTouch 函数,使砖块透明度随着时间的推移逐渐降低,直到完成循环后砖块消失并将 CanCollide 关闭。两秒后,它就恢复到正常状态。我认为问题在于我用来监视部件的编码,因为我不知道正确的监视多个对象的方法。有人可以帮忙吗?谢谢!

文件结构:

![文件结构](https://i.stack.imgur.com/dmDYk.png)

function onTouched(brick)
    local delay = .1 -- 透明度逐渐降低的延迟(影响消失速度)
    local RestoreDelay = 2 -- 砖块重新出现之前的延迟
    local inc = .1 -- 砖块每次消失的量

    -- 所有角色都有一个 Humanoid 对象
    -- 如果模型有一个,它就是一个角色
    local h =script.Child:findFirstChild("Humanoid") -- 在触摸到它的任何东西中查找 Humanoid
    if (h ~= nil) then -- 如果有 Humanoid
        h.Health = h.MaxHealth -- 将健康状况设置为最大(完全治愈)
        for x=0,1, inc do
            script.Child.Transparency = x+inc
            script.Child.CanCollide = true
            wait(delay)
        end
        wait(delay)
        script.Child.Transparency = 1
        script.Child.CanCollide = false
        wait(RestoreDelay)
        script.Child.Transparency = 0
        script.Child.CanCollide = true
    else
    end
end

while true do
    local bricks=script:GetChildren():IsA("basic.part")
    for x=1,brick in pairs(bricks) do
        brick.Touched:connect(onTouched(brick)) -- 当触摸时调用 onTouched
    end
end
end
点赞
用户2860267
用户2860267

大部分来说,你做得很好,但在 JavaScript 和 Lua 之间有一些不同的惯例,会导致一些语法错误。

在 JS 中,你可以获取对象数组并立即过滤它,但在 Lua 中,对此的支持有限。所以像 JavaScript 中这样一行代码:

var bricks = script.GetChildren().filter(function(item) {
   return item === "basic.part"
})

在 Lua 中不能一次性地完成,除非使用一些库的帮助。所以你需要将检查移到循环中,而不是在所有对象中进行过滤。

除此之外,另一个需要更改的是 onTouched 处理程序的函数签名。BasePart.Touched 事件告诉你哪个物体与砖块接触,而不是砖块本身。但是通过创建一个高阶函数,很容易获得访问砖块和接触它的物体的权限。

-- 创建一个助手函数来访问砖块和接触它的物体
function createOnTouched(brick)
    -- 记录动画是否正在运行
    local isFading = false

    return function(otherPart)
        -- 如果动画已经启动,就不要再做一次
        if isFading then
            return
        end

        local delay = .1 -- 消失速度的延迟(影响消失速度)
        local restoreDelay = 2 -- 砖块再次出现的延迟
        local inc = .1 -- 每次砖块消失的大小

        -- 所有角色都有一个 Humanoid 对象,检查是否有一个
        local h = otherPart.Parent:FindFirstChild("Humanoid")
        if h then
            -- 治疗玩家
            h.Health = h.MaxHealth

            -- 开始淡出砖块
            isFading = true
            brick.CanCollide = true
            for i = 0, 1, inc do
                brick.Transparency = i
                wait(delay)
            end
            -- 关闭砖块的碰撞
            wait(delay)
            brick.Transparency = 1
            brick.Anchored = true
            brick.CanCollide = false

            -- 将砖块重新打开
            wait(restoreDelay)
            brick.Transparency = 0
            brick.CanCollide = true

            -- 重置动画标志
            isFading = false
        end
    end
end

-- 循环遍历子项并连接触摸事件
local bricks = script:GetChildren()
for i, brick in ipairs(bricks) do
    if brick:IsA("BasePart") then
        local onTouchedFunc = createOnTouched(brick)
        brick.Touched:Connect(onTouchedFunc)
    end
end
2021-04-09 16:24:32