So you'd use something like this:
Note that my code doesn't handle the end-of-spectating, that will need even more magic (a global table of who's spectating, g_Spectating[SpectatorName] = SpectatedName) and the end-spectate command writing into that table. Also I didn't test the code at all, it might not even run.
local NUM_TICKS = 5 function HandleSpectateCommand(a_Split, a_Player) -- Store the player name of the spectator and the spectated player, so that you can access them later on: local SpectatorName = a_Player:GetName() local SpectatedName = a_Split[2] if (SpectatedName == nil) then -- TODO: handle error end local Callback = function(a_World) -- This is the callback that will be called after NUM_TICKS ticks -- Note that it CANNOT access a_Player! -- (because the player could have disconnected in the meantime and the object would be invalid then, making the server crash) -- Instead, we need to look up both players by name: a_World:DoWithPlayer(SpectatorName, function (a_Spectator) -- This function will be called and a_Spectator will be set to the cPlayer object of the spectator, *if* they exist a_World:DoWithPlayer(SpectatedName, function (a_Spectated) -- This function will be called and a_Spectated will be set to the cPlayer object of the spectated player, *if* they exist local pos = a_Spectated:GetPosition() pos.y = pos.y + 2 a_Spectator:TeleportToCoords(pos.x, pos.y, pos.z) a_World:ScheduleTask(NUM_TICKS, Callback) -- re-schedule for after another 5 ticks end ) -- DoWithPlayer(SpectatedName) end ) -- DoWithPlayer(SpectatorName) end -- Schedule the callback to be called after NUM_TICKS ticks: a_World:ScheduleTask(NUM_TICKS, Callback) end
Note that my code doesn't handle the end-of-spectating, that will need even more magic (a global table of who's spectating, g_Spectating[SpectatorName] = SpectatedName) and the end-spectate command writing into that table. Also I didn't test the code at all, it might not even run.