Hi, I need help about reverting a player position of 5 seconds ago. (I’m Spanish, sorry if I have mistakes)
My problem is saving the position
What do you want to achieve? Keep it simple and clear!
Revert player’s position of 5 seconds ago
What is the issue?
I don’t know a way of how to save the position constantly then when this activates, all players goes to their position of 5 seconds ago (Real issue is about saving position, I already know how to update position of before)
What solutions have you tried so far?
All I can do is to update position EVERY 5 seconds, but it won’t work exactly since it updates every 5 seconds and not every 0.1 second or every second.
I’m not very advanced at scripting, so please make examples if you can :D.
You can use something like this, which will update whenever the player moves. I do not know how expensive this will be though.
game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
Character.HumanoidRootPart.Changed:Connect(function()
print(Character.HumanoidRootPart.Position) -- This will print the Vector3 value which is X/Y/Z
end)
end)
end)
local OldPositions = {}
game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
while Character do
OldPositions[tostring(Player)] = Character.PrimaryPart.Position
wait(5)
end
end)
end)
function RevertPlayerPos(Player)
local OldPos = OldPositions[tostring(Player)]
if OldPos then
Player.Character:MoveTo(OldPos)
end
end
You’re waiting 5 seconds, which will cause problems because if the timer is in the middle of doing something while the player is being moved, the position won’t be correct.
I’m not sure if I understand. He said he wants to revert the players position to 5 seconds ago when a function is called.
Also @azahid1 the problem with signals is that if it is not properly gc’ed, they will accumulate and they will cause the game to crash (esp. true with large game servers). Read: PSA: Connections can memory leak Instances!
Actually to revise my script, you would need to add a timestamp. So what I am going to do is use a LocalScript instead.
local start = os.time()
local Positions = {
[1] = Vector3.new(0,0,0),
[2] = Vector3.new(0,0,0),
[3] = Vector3.new(0,0,0),
[4] = Vector3.new(0,0,0),
[5] = Vector3.new(0,0,0),
}
repeat wait() until game.Player.LocalPlayer.Character
while wait(5) do
start = os.time()
for i = 1,5 do
Positions[i].Value = game.Players.LocalPlayer.Character.HumanoidRootPart.Position
wait(1)
end
end
end
function getPreviousPosition()
local gettime = os.time()
if gettime - start > 0 then
return Positions[gettime-start]
else
return Positions[1]
end
end
So I don’t know how efficient cent this is but this should work. Create a table that holds every player’s position in the last 5 seconds. The table I made is going to look a little like this -
Then on another thread we are going to constantly update every Player’s position according to that Player’s os.time() in this table. To do so we will be using a couple loops -
coroutine.resume(coroutine.create(function()
while true do
for _,Player in pairs(game.Players:GetPlayers()) do
local playerChar = Player.Character
if playerChar ~= nil then
playerPositions[Player][os.time()] = playerChar:FindFirstChild("HumanoidRootPart").Position
end
if playerPositions[Player][(os.time() - 6)] ~= nil then --Get rid of any position 6 seconds ago
playerPositions[Player][(os.time() - 6)] = nil
end
print(playerPositions[Player][os.time()])
end
wait(1)
end
end))
Now to retrieve the Player’s position from 5 seconds ago we can do
playerPositions["PlayerName"][os.time() - 5]
For this method I am adding every position in the last 5 seconds so you could technically get the position from the last 1-5 seconds. You can probably modify this so it is only 5 seconds, but I like how it is it is a bit sloppy as I am doing this on my laptop but hopefully it works.
edit: There may be better ways to achieve this without os.time() and other things but this is just my take on solving your problem.
After reading some replies here, I’m not sure why some seem to store multiple positions. All you need is one position- the one from 5 seconds ago. (Per player, ofc)
This method will not move players who have been in the game for less than 5 seconds, as their position 5 seconds ago does not exist.
I’m on my phone, but I’ll try to type something up. Mobile really hates formatting code, sorry.
local PlayerPositions = {}
game:GetService("Players").PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Char)
Char:WaitForChild("HumanoidRootPart"):GetPropertyChangedSignal("CFrame"):Connect(function()
delay(4.98, function()
PlayerPositions[Player] = Char.HumanoidRootPart.CFrame
end)
end)
end)
end)
game.Players.PlayerRemoving:Connect(function(Player)
PlayerPositions[Player] = nil
end)
local function Revert()
for plr,cf in pairs(PlayerPositions) do
plr.Character.HumanoidRootPart.CFrame = cf
end
end
The reason why we are storing multiple values is because the script OP is talking about wants to move ALL players, which means that in the function that you are using all the players will not be synced because there is little chance they will all start moving at the same time, and the whole thing with new players joining.