So I’ve been trying to make a function that uses a position, direction, jump height, walk speed, and other variables to calculate a jumping trajectory to find a valid node for the rest of the pathfinding script.
Currently I have a working version; the problem is that the function is far too resource-intensive, and I don’t know how I could optimize it without breaking it or making it too slow using waits.
Also, the function uses some other functions to work and is in a module script.
Basically, how can I optimize this function or the functions that it uses?
The function in question.
function module:Hop(From_Position:Vector3, Direction:Vector3, Grid:table, limit:Vector3, Jinfo:Vector2, Params:RaycastParams, PF)
local Speed, JumpHeight = Jinfo.X, Jinfo.Y-- /\ /\ /\ Grid is a 3d table, limit is size of table and PF is a table of all the parts that Grid Nodes use
local Delta, Vy, Arrow = 0, math.sqrt(2*workspace.Gravity*JumpHeight), Is_In_SD(Direction)
local CD = true--goes to other direction | /\ /\ /\ delta is the angle, Vy is needed for calculations, Arrow is given direction in array
local Tinterval = (2*Vy)/workspace.Gravity--Time increase interval
while Delta < 4 do
local DIRECTION, Chspeed = SD_array[FSNX(Arrow+Delta)], Speed-- Direction from resulting delta
while Chspeed >= 2 do
local Time = Tinterval/2-- The current time
local prev = From_Position-- the previous position
while Time < 2*Tinterval do
local Result = Vector3.new(From_Position.X+DIRECTION.X*Chspeed*Time, From_Position.Y+Vy*Time-(workspace.Gravity/2)*Time^2, From_Position.Z+DIRECTION.Z*Chspeed*Time)
local D = (Result-prev)-- /\ /\ /\ Resulting position
local RAY = workspace:Raycast(prev, D, Params)-- ray
if pcall(function() local a = RAY.Instance end) then
local Hit_Loc = GCNgp(From_Position + (RAY.Position-From_Position)+Vector3.new(0, 0.2, 0), PF)
if not Is_Valid(Hit_Loc, limit) then-- /\ /\ /\ returns the grid position from world position
break-- checks if grid_location is valid
end
local Hit_Node = Grid[Hit_Loc.Y][Hit_Loc.Z][Hit_Loc.X]-- Node
if Hit_Node.Type == "Jump" or Hit_Node.Label == "Blocked" then
break-- if node is not walk, edge, climb then break loop
end
task.wait()
return Hit_Node-- return node if found
end
prev = Result-- set previous and increase time
Time += Tinterval/2
end
Chspeed /= 2-- decrease speed
end
if CD then-- 0, 2, -2, 4
CD = false
if Delta < 0 then
Delta *= -1
end
Delta += 2
else
CD = true
Delta *= -1
end
end
return nil-- if nothing found then return nil
end
–
The local functions that this function uses
–
local Q, Delta = Vector3.new(1, 0, 1)/math.sqrt(1^2+1^2), math.pi/8
local SD_array = {
Q,
Vector3.new(math.cos(Delta)*Q.X+math.sin(Delta)*Q.X, 0, -math.sin(Delta)*Q.Z+math.cos(Delta)*Q.Z),
Vector3.new(math.cos(2*Delta)*Q.X+math.sin(2*Delta)*Q.X, 0, -math.sin(2*Delta)*Q.Z+math.cos(2*Delta)*Q.Z),
Vector3.new(math.cos(3*Delta)*Q.X+math.sin(3*Delta)*Q.X, 0, -math.sin(3*Delta)*Q.Z+math.cos(3*Delta)*Q.Z),
Vector3.new(math.cos(4*Delta)*Q.X+math.sin(4*Delta)*Q.X, 0, -math.sin(4*Delta)*Q.Z+math.cos(4*Delta)*Q.Z),
Vector3.new(math.cos(5*Delta)*Q.X+math.sin(5*Delta)*Q.X, 0, -math.sin(5*Delta)*Q.Z+math.cos(5*Delta)*Q.Z),
Vector3.new(math.cos(6*Delta)*Q.X+math.sin(6*Delta)*Q.X, 0, -math.sin(6*Delta)*Q.Z+math.cos(6*Delta)*Q.Z),
Vector3.new(math.cos(7*Delta)*Q.X+math.sin(7*Delta)*Q.X, 0, -math.sin(7*Delta)*Q.Z+math.cos(7*Delta)*Q.Z),
Vector3.new(math.cos(8*Delta)*Q.X+math.sin(8*Delta)*Q.X, 0, -math.sin(8*Delta)*Q.Z+math.cos(8*Delta)*Q.Z),
Vector3.new(math.cos(9*Delta)*Q.X+math.sin(9*Delta)*Q.X, 0, -math.sin(9*Delta)*Q.Z+math.cos(9*Delta)*Q.Z),
Vector3.new(math.cos(10*Delta)*Q.X+math.sin(10*Delta)*Q.X, 0, -math.sin(10*Delta)*Q.Z+math.cos(10*Delta)*Q.Z),
Vector3.new(math.cos(11*Delta)*Q.X+math.sin(11*Delta)*Q.X, 0, -math.sin(11*Delta)*Q.Z+math.cos(11*Delta)*Q.Z),
Vector3.new(math.cos(12*Delta)*Q.X+math.sin(12*Delta)*Q.X, 0, -math.sin(12*Delta)*Q.Z+math.cos(12*Delta)*Q.Z),
Vector3.new(math.cos(13*Delta)*Q.X+math.sin(13*Delta)*Q.X, 0, -math.sin(13*Delta)*Q.Z+math.cos(13*Delta)*Q.Z),
Vector3.new(math.cos(14*Delta)*Q.X+math.sin(14*Delta)*Q.X, 0, -math.sin(14*Delta)*Q.Z+math.cos(14*Delta)*Q.Z),
Vector3.new(math.cos(15*Delta)*Q.X+math.sin(15*Delta)*Q.X, 0, -math.sin(15*Delta)*Q.Z+math.cos(15*Delta)*Q.Z)}
local function Is_In_SD(Direction:Vector3)-- Uses given array so to use premade directions instead
local Simp = Direction * Vector3.new(1, 0, 1)
local Max = math.huge
local Array, N = {}, 0
for _, D in ipairs(SD_array) do
local Dist = (D-Direction).Magnitude
if Dist < Max then
Max = Dist
table.insert(Array, table.find(SD_array, D))
N += 1
end
end
return Array[N]
end
local function FSNX(N:number)-- converts number for use in SD_Array
if N < 1 then
return N+16
end
if N > 16 then
return N-16
end
return N
end
local function GCNgp(From:Vector3, PF_children:table)-- returns Grid_Location of a node from given world position
local temp, index, max = {}, 0, 9999
for _, child in ipairs(PF_children) do
local dist = (child.Position - From).Magnitude
if dist < max then
max = dist
index += 1
temp[index] = child
end
end
return temp[index]:GetAttribute("Grid_Location")
end
local function Is_Valid(pos:Vector3, limit:Vector3)-- checks if given grid_location is inside of grid size
if pos.Y < 1 or pos.Y > limit.Y then
return false
end
if pos.Z < 1 or pos.Z > limit.Z then
return false
end
if pos.X < 1 or pos.X > limit.X then
return false
end
return true
end
Ive tried using #native with !optimize2 but it hasn’t helped much and ive tried waits but they make the function way to slow sooooooooooooooooooooooooooooooooooooooo yea.