I made a little follow the leader code for something and I wanted to share what I did so others don’t need to suffer. No one is probably gonna use it but imma put it out here in case anyone in the future needs reference.
function followTheLeader(dt, url, DistnSpeed, leaderObj, trainList)
--url, url of GAMEOBJECT (not script)
--DistnSpeed, table of maxDist, minDist, and maxSpeed
--leaderObj, if it moves we all move. Url to this object.
--trainList, list of party members (object urls), discluding leader
local tl = trainList --this is like this bc its taken from another code snippet that needed me to do this
local lo = leaderObj
--finds out where the object is in the train. Compares this object's url to all the urls in the trainlist
local index = 0
for i, follower in ipairs(tl) do
if url == follower then index = i end
end
if index == 0 then --[[print("ur not invited to the party lmao loser");]] return end
local toFollow = lo
if index > 1 then toFollow = tl[index - 1] end -- if not the second item in the train, follow the item behind it (second object follows leader)
local tfp = go.get_position(toFollow) --tfp = position of object being followed
local dns = DistnSpeed --reduntant code bc i didnt wanna write this variable multiple times lol
local speed = 350
timer.delay(dt + 0.01, false, function() --this was ran in a program running at 30fps, if you have an issue feel free to change the offset
local tfn = go.get_position(toFollow) --tfn = new position of object being followed
local timedist = tfn - tfp; --distance between the old and new positions of the old object. This is to detect if there was movement.
if timedist ~= vmath.vector3(0) then -- if there was movement then...
local myp = go.get_position() -- get object pos
local newdist = tfn - myp --calculate distance vector
local intdist = math.sqrt((myp.x - tfn.x)^2 + (myp.y - tfn.y)^2) -- find absolute distance using the trusty old pythagorean theorem
if intdist < dns.minDist then -- slow down if too close
speed = speed * intdist/dns.minDist
elseif intdist > dns.maxDist then --speed up if too far
speed = speed * (intdist/dns.maxDist)
end
if dns.maxSpeed then
speed = math.min(speed, dns.maxSpeed) -- this is for the slow pokes out there
end
newdist = vmath.normalize(newdist) * dt * speed --normalize distance vector and multiply by speed and dt
go.set(".", "position.x", myp.x + newdist.x)
go.set(".", "position.y", myp.y + newdist.y)
--you can just use go.set_position, i didnt here because im using y-axis z sorting
end
end)
end
Then inside the update functions inside the scripts inside of the objects that are following:
function update(self, dt)
local leaderObject = msg.url("/leader")
local trainList = {--[[List of objects. I personally think its better to put this in
a module for multiple scripts]]}
followTheLeader(dt, msg.url("."), {minDist = 150, maxDist = 200 --[[maxSpeed = if you want a max speed]]}, leaderObject, trainList)
end
PS: If you have a slow poke in the middle of the line, it WILL hold up that line!!