When I teleport a player by modifying the RootPart’s CFrame, the RootPart’s CFrame stays in the same place like nothing happened.
I am unable to provide visuals or anything basically related to it other than providing a sample code which isn’t enough since the bug happens rarely, and I have been getting some reports on it.
local function Teleport(Player, Position)
Player:RequestStreamAroundAsync(Position)
if Player.Character and Player.Character.PrimaryPart then
Player.Character.PrimaryPart.CFrame = CFrame.new(Position)
end
end
A function similar to the one provided is the one used always in the game to teleport players around the map. It tends to work 95% of the time (rough estimate), since sometimes it fails to teleport you. I ran prints per each line and the code seems to go through properly every time, but you stay in the same location you are in, is like the change in CFrame is ignored or not even replicated.
I imagine this is related to StreamingEnabled since when I turned it off, the player who managed to replicate it multiple times in a row was always teleported and unable to replicate the bug. However, when I turned it back on, the player did not get teleport like 5-10% of the times.
StreamingEnabled settings: (Note I also have the PhysicsSteppingMethod set to Active)
Expected behavior
I expect when I teleport players using the RootPart’s CFrame for them to move to that location.
Thank you, I would be glad if someone lets me know what is going on here…
Are you able to provide a simple repro place that demonstrates the issue?
It looks like you are not supplying a timeout to the RequestStreamAroundAsync call, which means it could be waiting a long time for the request to complete. If you provide a timeout do you still encounter the same problems?
I am unable to provide a repro-place, except for the game itself: Game
So I am not supplying a timeout to the function call; however, is not like is yielding for long periods of time and not teleporting users. It seems like the game does complete the request, resumes the coroutine, and does everything else. I had prints for me to see and the prints were going through all the time.
These prints I displayed in chat as well, so the user who was trying the bug would see it:
Teleport 1 is the function call
Teleport 2 is an if statement I have in the original code
Teleport 3 is before the Streaming request.
Teleport 4 is when the CFrame is changed.
You were teleported! is when the function ends and switches back to the one who called the function Teleport.
Are you performing the CFrame in a local script, or on the server? Is it possible the player is outside the streamed area or paused when you try and perform the CFrame?
The CFrame change happens on Server and the areas the player is always teleported to could not be loaded in since the map is big, which is why StreamAroundAsync is called.
By any chance, are you attempting set CFrame on the character immediately after breaking a weld or doing anything else that could change the AssemblyRootPart of the character?
Wonder if it’s this same old issue:
There’s a fundamental ordering dependency between CFrame changes and assembly structure changes, but the replicator treats them as if there was no ordering constraints.
In some cases it can send the CFrame assignment before the other property assignments that made that part an assembly root, causing the CFrame assignment to be ignored because that part isn’t an assembly root (yet).
At one point I had a fix for this code complete, but it never shipped. It’s complicated.
If this is the same issue you might be able to workaround this by also sending a redundant teleport notification to the teleported player as a RemoteEvent. That RemoteEvent is currently guaranteed to go to the bottom of the queue, after all the property changes affecting assembly structure, and fired after all those property changes are applied. Locally check that the AssemblyRootPart is still HumanoidRootPart (remember this will move any vehicles or other objects welded to the character!), and set CFrame. That local client-side assignment will succeed either way (it’s unconditionally re-routed to the root, unlike the replicated assignment which is dropped if not root) and then that character movement will be re-broadcast through the physics sender.
Do both because if the character is server owned, the server assignment is the one that matters, which succeed on the server. If client owned, it still needs help in some cases currently (after unseating etc).
Hello there! Well, no, unless tool equipping/unequipping or something related can be considered breaking welds. Players can also equip armors/cosmetics, which have welds. Aside from that though, only tools could be the ones changing during teleportation.
Do you think using PivotTo on the Player’s model would actually fix the issue like I saw in that post?
Very large parts (much larger than the root part) welded to the character or constraints connected to other assemblies can also cause AssemblyRootPart of the character to change.
If you have someone with a consistent repro it might be worth logging what character’s AssemblyRootPart is in a few places and seeing if it ever changes.
If the root part ever changes, it might be this old issue.
That old issue does happen more easily when the replicator’s internal queue gets backlogged. Typically when there are a lot of properties changing or remote events firing.
If root part is never changing we might have a new bug!
So it seems that the AssemblyRootPart of the HumanoidRootPart block is itself all the time while player is being teleported. (After changing CFrame on server the message in chat was sent through remote event for the client to display)
I changed the RootPriority on the HumanoidRootPart to 1 and didn’t fix it either.
I tried Model:PivotTo() and it didn’t work either.
Last thing will be Anchoring or maybe teleporting the player client side like mentioned, but I don’t want to anchor players neither do this. I guess as a work around though I might need to rely on it…