砖块生成脚本Y轴位置指数异常的原因问询(已解决)
我写了个用来生成大量砖块的脚本,原本是给可破坏场景(比如箭靶场)做基础的。一开始砖块尺寸是2x2x2,后来为了优化性能改成4x4x4,结果改完之后脚本在Y轴方向出现了指数级的位置异常。
原脚本代码:
-- Origin == {POS = 0,0,0; SIZE = 4,4,4} -- Finality == {POS == -477, 2, 243; SIZE = 4,4,4} local location = {X = script.Origin.Position.X, Y = script.Origin.Position.Y, Ymoved = script.Origin.Position.Y, Z = script.Origin.Position.Z} --[[Previously Ymoved started at Origin.Position and went up how many tiles we went per floor.]] local MATZ = {"Marble","Ice"} local Colours = {Color3.new(0.25, 0.25, 0.25),Color3.new(0.811765, 0.992157, 1)} local locationEnd = script.Finality.Position local count = 0 local Vector = Vector3.new while true do local brick = Instance.new("Part", game.Workspace) --Main Part creation brick.Name = "Brick_"..count brick.Position = Vector(location.X, location.Y, location.Z) brick.Size = Vector(4,4,4) brick.Anchored = true --Prettify (needs more options) local SEED = math.random(1,2) brick.Material = MATZ[SEED] brick.Color = Colours[SEED] if location == locationEnd then --unsafe, needs to be changed once i actually have an endpoint... break elseif location.X >= locationEnd.X then location.X = script.Origin.Position.X location.Z = location.Z - 4 print("Next column") elseif location.Z <= locationEnd.Z then location.X = script.Origin.Position.X location.Z = script.Origin.Position.Z location.Ymoved = location.Ymoved + 2 location.Y = script.Origin.Position.Y + location.Ymoved --This line is antibepis print("Next floor") end if count % 250 == 0 then wait() end location.X = location.X + 4 count = count + 1 end
排查后发现问题出在Y轴的位置更新逻辑上,先看两种错误写法的问题:
第一种写法会导致砖块在Y轴指数级靠拢:
location.Ymoved = location.Ymoved + 2 location.Y = script.Origin.Position.Y + location.Ymoved
改成第二种写法后,每层砖块又会指数级远离:
location.Ymoved = location.Ymoved + 2 location.Y = location.Y + location.Ymoved
最后用直接的写法解决了问题:
location.Y = location.Y + 4
为什么会出现指数级异常?
第一种写法的问题:
Ymoved初始值是原点Y坐标(假设为0),每次触发换楼层逻辑时,Ymoved都会累加2。但脚本中换楼层的判断条件location.Z <= locationEnd.Z可能在循环中被多次触发(比如Z轴位置未正确复位时),导致Ymoved被反复累加,增长速度从预期的线性变成了触发次数的累加,最终形成指数级增长,Y轴位置自然出现异常靠拢。第二种写法的问题:
改成location.Y = location.Y + location.Ymoved后,Y轴的增量是当前的Ymoved值,而Ymoved本身一直在累加。比如第一次换楼层时Ymoved=2,Y从0变成2;第二次Ymoved=4,Y变成2+4=6;第三次Ymoved=6,Y变成6+6=12……这种“增量本身不断变大”的逻辑,会让Y轴的增长变成累加的累加,也就是二次增长,视觉上就呈现出指数级远离的效果。
为什么2x2x2尺寸时没这个问题?
一是原来的尺寸下,对应的Y轴增量(比如每次加1)和触发条件刚好匹配,换楼层的逻辑不会被多次触发,Ymoved的累加处于可控状态;二是2x2x2的尺寸很小,即使有微小的累加异常,视觉上也不容易察觉,改成4x4x4后,每次增量变成2,异常被放大,就明显表现出来了。
内容的提问来源于stack exchange,提问作者Link_jon

