I've been creating a windfield system in Luau (Roblox). I'm creating arrays for the winddata with the key being a Vector3
converted to string format. However, I'm struggling to find the best way to loop through check if parts in the workspace at the position (key converted back to Vector3
). My Code:
--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local WindArrow = ReplicatedStorage:WaitForChild("WindArrow")
local module={}
module.WindfieldClass={}
module.WindfieldClass.__index=module.WindfieldClass
--Math Functions
local function roundVector3ToIncrement(n: Vector3, increment: number): Vector3
return Vector3.new(math.floor((n.X / increment) + 0.5) * increment,
math.floor((n.Y / increment) + 0.5) * increment,
math.floor((n.Z / increment) + 0.5) * increment
)
end
--Misc Functions
function module.vector3Key(v: Vector3): string
return v.X .. "," .. v.Y .. "," .. v.Z
end
function module.stringToVector3(s: string): Vector3
local x, y, z = string.match(s, "([^,]+),([^,]+),([^,]+)")
return Vector3.new(tonumber(x), tonumber(y), tonumber(z))
end
function module.WindfieldClass.new()
local self={
WindVA={
},
WindHA={
},
Visualized=false,
Resolution=1
}
self=setmetatable(self,module.WindfieldClass)
return self
end
function module.WindfieldClass:add(Position:Vector3,Orientation:number,Type:string,WindSpeed:number)
if Type=="HA" then
local ori=Vector3.new(0,Orientation,0)
Position=roundVector3ToIncrement(Position,self.Resolution)
self.WindHA[module.vector3Key(Position)]={
Orientation=Orientation,
WindSpeed=WindSpeed
}
elseif Type=="VA" then
local ori=Vector3.new(0,0,180)
Position=roundVector3ToIncrement(Position,self.Resolution)
self.WindHA[module.vector3Key(Position)]={
Orientation=Orientation,
WindSpeed=WindSpeed
}
else
warn("Type "..Type.." is invaid!")
end
end
function module.WindfieldClass:visualize(mode:number,Dest:Instance)
if self.Visualized then
if mode==0 then
for key,data in pairs(self.WindHA) do
local clone=WindArrow:Clone();clone.Position=module.stringToVector3(key);clone.Orientation = Vector3.new(0, data.Orientation, 0)
clone.Parent=Dest
end
end
end
end
function module.WindfieldClass:simulate()
end
return module
The goal of this code (haven't added it yet) is to get the part's in the arrays created by module.WindfieldClass.new()
, and move the part's CFrame based on both tables- WindVA
for the lift table (vertical movement). and WindHA
for horizontal movement (x
and z
).
I've tried looping through all parts that meet the criteria, but with a lot of destructable parts, it's really laggy.
What is the best way of achieving this?
If I were to optimize your code, I would only make a few changes :
Vector3
as your keys, not a string version of it. It saves the step of encoding and decoding it.-- create a luau type to allow for compile-time validation of inputs
export type WindfieldType = "HA" | "VA"
function module.WindfieldClass:add(Position:Vector3, Orientation:number, Type:WindfieldType, WindSpeed:number)
local ori
if Type=="HA" then
ori = Vector3.new(0, Orientation, 0)
elseif Type=="VA" then
ori = Vector3.new(0, 0, 180)
else
warn("Type "..Type.." is invaid!")
return
end
local key = roundVector3ToIncrement(Position, self.Resolution)
self.WindHA[key] = {
Orientation = ori,
WindSpeed = WindSpeed
}
end
-- ...
function module.WindfieldClass:visualize(mode:number, Dest:Instance)
if not self.Visualized then
return
end
if mode == 0 then
for key,data in pairs(self.WindHA) do
local clone = WindArrow:Clone()
clone.Position = key
clone.Orientation = data.Orientation
-- perhaps try to scale the clone by how fast the wind speed is moving?
-- clone.Size *= data.Windspeed
clone.Parent = Dest
end
end
end
Folder
in the Workspace
, or create a table to track the objects.-- in a Script somewhere...
-- find the objects that need to move, be sure to parent objects to this Folder
local objectsFolder : Folder = game.Workspace.SimulatedObjects
for i, child in ipairs(objectsFolder:GetChildren()) do
-- apply forces from the wind field to each child object...
end
The goal of optimization is to look at your code, and the operations you do, and try to figure out what you have "too many" of. In your case, your loops have too many objects that they are stepping over. So your goal should be to find ways to reduce that by tracking only the objects you care about.