What Happens
When using HumanoidRootPart.Position, HumanoidRootPart.CFrame, Character:PivotTo(), or Character:MoveTo() to teleport the player to a different location within the same place, the position HumanoidRootPart (HRP) of the player’s character model no longer corresponds to the position of said player’s character model. The actual position of the HRP is offset from the character model as shown in the provided images.
What Should Happen
What I expect to happen is that the player’s character model remains intact during and after the teleport.
Where it Happens
It happens in the live game, in studio, and in a component test place (within studio). The live test game can be found here: The Proving Grounds.
When it Happens
I do not know when this started happening, but from the information that I have been able to gather, this has been ongoing for some time. I only noticed it when after teleporting, the game started to experience game-breaking issues.
For instance:
Weapons that rely on the position of the end of the gun barrel do not have their effects generated in the proper location (Lightning Gun)
Firing any type of rocket launcher style weapon results in the player ending back up in the teleporter.
Additional Evidence
In the below image, before teleporting, everything is normal.
I haven’t dug all the way into this, but the key issue is setting .Position on HumanoidRootPart. If you simply change the root.Position = position to root.CFrame = root.CFrame.Rotation + position that will resolve the issue for now.
(And we’re still going to investigate what underlying unintentional behavior change happened)
After I posted the bug report, I found that the outgoing teleport function was doing root.Position. I changed it and is working correctly now. From my research on this issue, I have found that setting the character position using HumanoidRootPart.Position = position has been a long standing issue. I’m not sure what the difference between HumanoidRootPart.Position = position and HumanoidRootPart.CFrame = CFrame.new(position) is internally as the first one just supposedly sets the position while the second one also sets the rotation matrix.
This issue should definitely be fixed, I can see this behavior being very confusing for new scripters. But how would they go about fixing it? What would break?
I’m assuming that the change would only be good, but people will find a way to be angry about it, as always. Either that, or their game would actually break.
I also encountered this recently when seeing a bug with ProximityPrompts not activating correctly.
I didn’t realise this had been reported so I made a repro place showing the true position of the character on the client - here it is in case it’s helpful.
Hope this can be fixed soon, but it can be worked around. Thanks! rootpart teleport reproduction.rbxl (47.2 KB)
It’s definitely a coding trap for the unwary. It took me some time to figure out what was going on before I was able to narrow it down. Changing the character’s position using HumanoidRootPart.Positionshould work, but it doesn’t work correctly. I cannot think of a situation where I would want it to behave like that.
This is behavior is expected for assemblies with welds. The behavior of Part.Position is documented: it moves only the part without moving the entire assembly.