使用lua和Roblox Studio改善性能

问题描述 投票:0回答:2

我终于使用lua和Roblox Studio完成了我的第一个脚本。目标是让一组瓷砖在玩家踩踏时改变颜色。

这是我的代码:

local parts = {}
for k, v in pairs(game.Workspace:GetDescendants()) do
    if string.sub (v.name, 1, 4) == "Part"  then
        table.insert(parts, v)
    end
end

local char = workspace:WaitForChild("localPlayer") 

local hrp = char:WaitForChild("HumanoidRootPart")

local newThread = coroutine.create(function()

game:GetService("RunService").Heartbeat:Connect(function()
    local charpos = hrp.Position

    for k, v in pairs (parts)do
        if (charpos - v.CFrame.Position).magnitude <= 6 then
            local pos = v.CFrame.Position
            for k, v in pairs(parts) do
                if v.CFrame.Position.X == pos.X or v.CFrame.Position.Z == pos.Z then
                    v.BrickColor = BrickColor.new("Really red")
                    print("touching")
                end
            end
            return
        else
            v.BrickColor = BrickColor.new("Medium stone grey")
            print("not touching")
        end
    end
end)

end)

coroutine.resume(newThread)

此作品:

enter image description here

但是我的项目需要更多的瓷砖和更多的颜色。当我增加平台等的数量时,程序变得非常缓慢。

enter image description here

gif并没有真正显示出多长时间,但是它变得越来越差,在播放大约一分钟后,您几乎无法有效控制播放器。

如您所见,我试图将我的函数放在一个协同例程中,但这没有帮助。我对lua和trying制作游戏非常陌生,所以我真的不知道如何提高性能。滞后变得越来越糟的事实似乎表明记忆没有得到有效释放?我以为这是自动发生的。无论如何,任何帮助都将不胜感激。

performance lua lag roblox heartbeat
2个回答
0
投票

较小更改-循环制作新BrickColor的结构。它的值在不受影响的部分不会改变,没有理由重复创建它。

并且查看是否打印大量调试信息会影响性能,所以请注释掉打印件。

第二,可能应该将块的网格重新组织为二维数组。因此,您不必扫描所有零件即可找到具有相同X / Z坐标的零件。这也将为您提供快速找到最接近的砖块的方法,在常规网格上这是微不足道的。


0
投票

您的功能不在协程内部,仅与信号的连接在内部。但是,由于心跳代码在每个帧上运行,因此使用协程将工作分派到另一个线程,直到下一个帧才开始工作,这无济于事。因此,请尝试寻找方法以最小化函数的计算工作,而不是使用线程。

平方根的计算很昂贵,所以我认为最好的优化是尽量减少距离检查的次数。

我建议使Heartbeat函数充当更可靠的TouchEnded处理程序,但只有在知道有玩家触摸它们的平台上才能使用它。然后,您可以使用零件的Touched处理程序来了解哪些平台具有播放器。

-- initialize some script globals
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

-- grab all the platforms and create a table of custom objects with data we care about
local platforms = {}
for _, part in ipairs(game.Workspace:GetDescendants()) do
    if string.sub (v.name, 1, 4) ~= "Part"  then
        continue
    end

    local platformData = {
        Part = part, -- the original object
        Touches = {}, -- a map of players actively touching it
    }

    -- initialize any events on these parts
    part.Touched:Connect(function(otherPart)
        -- when touched, check which player it is, and hold onto that information
        local player = Players:GetPlayerFromCharacter(part.Parent)
        if not player then
            warn(string.format("unexpected object touched a platform. Ignoring %s", part.Parent.Name))
            return
        end

        platformData.Touches[player.PlayerId] = player
    end)

    -- hold onto this data
    table.insert(platforms, platformData)
end

-- make a function that updates colors
RunService.Heartbeat:Connect(function()
    for _, platform in ipairs(platforms) do
        local isTouched = next(platform.Touches) ~= nil

        -- quick escape for inactive platforms
        if not isTouched then
            continue
        end

        -- check if the previous players are still touching it
        isTouched = false
        for id, player in pairs(platform.Touches) do
            local platPos = platform.Part.Position
            local hrp = player.Character.PrimaryPart
            local charPos = hrp.Position
            local dist = (platPos - charPos).magnitude

            if dist < 6 then
                isTouched = true
            else
                -- this player is no longer touching, remove them
                platform.Touches[id] = nil
            end
        end

        -- update the color of the platforms
        if isTouched then
            platform.Part.BrickColor = BrickColor.new("Really red")
        else
            platform.Part.BrickColor = BrickColor.new("Really blue")
        end
    end
end)

我希望这会有所帮助!祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.