作者:mobiledu2502883787 | 来源:互联网 | 2023-09-17 11:22
我终于使用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)
这有效:
但是我的项目需要更多的瓷砖和更多的颜色。当我增加平台等的数量时,该程序变得非常缓慢。
该gif并没有真正显示出多长时间,但是它变得越来越差,在播放大约一分钟后,您几乎无法有效控制播放器。
如您所见,我尝试将函数放在协程中,但这没有帮助。我对lua和 trying 制作游戏非常陌生,所以我真的不知道如何提高性能。滞后变得越来越糟的事实似乎表明记忆没有得到有效释放?我以为这是自动发生的。无论如何,任何帮助都值得赞赏。
在提出建议之后,我尝试了以下方法:
Hi,I have tried this:
local Platform = {}
local maPart = Platform.part
local function makePart(pX,pY,pZ)
maPart = Instance.new("Part",workspace)
maPart.Position = Vector3.new(pX,pZ)
maPart.Size = Vector3.new(10,10)
return maPart
end
local columns = {}
local rows = {}
for i = 1,12 do
columns[i] = rows
table.insert(columns,rows)
for j = 1,12 do
maPart = makePart(i*16,j*16)
rows[j] = maPart
table.insert(rows,maPart)
end
end
columns[1].[1].BrickColor = BrickColor.new("Really blue")
作为练习,我是否可以使“多维数组”这个新概念起作用。最后一行不起作用。我将如何访问数组内部数组中的元素? tx
较小的更改-循环使用新的BrickColor。在未受影响的部分,它的值不会改变,没有理由重复创建它。
并查看打印大量调试信息是否会影响性能,所以请注释掉打印件。
第二,可能应该将块的网格重新组织为二维数组。因此,您不必扫描所有零件即可找到具有相同X / Z坐标的零件。这也将为您提供快速找到最接近的砖块的方法,在常规网格上这是微不足道的。
,
您的功能不在协程内部,只有信号连接在其中。但是,由于心跳代码在每个帧上运行,因此使用协程将工作分派到另一个线程,直到下一个帧才开始工作,这无济于事。因此,请尝试寻找方法以最大程度地减少函数的计算工作量。
打印语句可能会使速度变慢,因此请在知道逻辑有效的情况下将其注释掉。平方根的计算非常昂贵,因此我认为最好的优化方法是最小化距离检查的次数。
我建议使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)
我希望这会有所帮助!祝你好运!