Character goes insane after changing the position of the HumanoidRootPart

Hello!
I made a script that teleports a player to a part in the workspace.

script.Parent.Touched:Connect(function(hit)
	if game.Players:GetPlayerFromCharacter(hit.Parent) then
		hit.Parent:WaitForChild("HumanoidRootPart").Position = game.Workspace.TpPoint.Position
	end
end)

This does work but for some reason my character is extremely buggy. I don’t really know how to explain this but ill try: The walkspeed stays the same if i press W/S (forwards or backwards). But when I press D/A (left or right) my character moves insanely fast. Sometimes it also teleports the character back to the TpPoint when I move it after it has been teleported already. How is this even possible and how do I fix this? Thanks for reading!

2 Likes

Try setting its CFrame instead of its position.

4 Likes

This is expected behavior. Roblox provides the Model | Roblox Creator Documentation function for teleporting models. However, according to this update announcement this function will soon be deprecated, so you should instead use PVInstance | Roblox Creator Documentation once the update goes live. However, until then you should use Model:SetPrimaryPartCFrame because the Pivot API isn’t fully released yet and is also missing documentation.

Here is a code same for you to use:

script.Parent.Touched:Connect(function(hit)
	if game.Players:GetPlayerFromCharacter(hit.Parent) and hit.Parent:IsA("Model") then
		hit.Parent:SetPrimaryPartCFrame(game.Workspace.TpPoint.CFrame)
	end
end)

However, because we are so close to the release of the Pivot API I feel that I would be remiss if I did not include a code sample using the upcoming Pivot API. So here it is:

Pivot API Code Sample
script.Parent.Touched:Connect(function(hit)
	if game.Players:GetPlayerFromCharacter(hit.Parent) and hit.Parent:IsA("PVInstance") then
		hit.Parent:PivotTo(game.Workspace.TpPoint.CFrame)
	end
end)
3 Likes

I don’t think you even have to use :SetPrimaryPartCFrame as the joints make it stay consistent when modifying the CFrame. For some reason, this doesn’t work when setting the position and gives odd behaviour.

Position:

workspace['7z99'].HumanoidRootPart.Position = Vector3.new(0,20,0)

Result:

CFrame:

workspace['7z99'].HumanoidRootPart.CFrame = CFrame.new(0,20,0)

Result:

Another thing, joints are more reliable than :SetPrimaryPointCFrame as that function can cause floating point errors. That bug is as old as time itself and it’s honestly really annoying.

2 Likes

You should try something like this to ensure you don’t get shoved in the ground:
This will add 5 studs of height so your player won’t get shoved in the ground.

script.Parent.Touched:Connect(function(hit)
	if game.Players:GetPlayerFromCharacter(hit.Parent) then
		hit.Parent:WaitForChild("HumanoidRootPart").Position = game.Workspace.TpPoint.Position + Vector3.new(0,5,0)
	end
end)
2 Likes

In Roblox’s article CFrames | Roblox Creator Documentation they use the :SetPrimaryPartCFrame method. Also, I’m not certain that the function will cause floating point offsets with joints. Also, after the Pivot API is released they are adding internal relative position cacheing so that the function will no longer produce the floating point offsets.

3 Likes