Tween player - lots of jittering

I want to tween the player “up and over” a small distance. The problem is that no matter what I’ve tried, the player “jitters” and/or the camera doesn’t follow the player:

Here’s the code:

			local player = Players.LocalPlayer
			local dest = HrpLastBounceCf
			local humanoid = player.Character:FindFirstChild("Humanoid")
			local hrp = player.Character:FindFirstChild("HumanoidRootPart")
			anchorForTween(true, hrp)

			-- first tween straight up just above where the HRP started
			local upDest = CFrame.new(
				Vector3.new(hrp.Position.X, dest.Position.Y + 2, hrp.Position.Z),
				dest.LookVector
			)
			local upTween = TweenService:Create(
				hrp,
				TweenInfo.new(3, Enum.EasingStyle.Quad),
				{ CFrame = upDest }
			)

			-- then to the final location
			local overDest = CFrame.new(
				Vector3.new(dest.Position.X, dest.Position.Y + 2, dest.Z),
				dest.LookVector
			)
			local overTween = TweenService:Create(
				hrp,
				TweenInfo.new(3, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
				{ CFrame = overDest }
			)

			upTween.Completed:Connect(function()
				Debris:AddItem(upTween)
				overTween:Play()
			end)

			overTween.Completed:Connect(function()
				Debris:AddItem(overTween)
				anchorForTween(false, hrp)
				PortingBack = false
			end)

			upTween:Play()

This is the anchorForTween function I’m using to anchor the HumanoidRootPart descendants (per post linked below)

local function anchorForTween(anchored, hrp)
	for _, child in pairs(hrp:GetDescendants()) do
		if child:IsA("BasePart") then
			child.Anchored = anchored
		end
	end
end

Things I’ve tried:

  • Running this with the HumanoidRootPart anchored according to this and not anchored (same behavior).
  • Running on client and using a remote event to run it on the server… similar results on both. Although I’m a bit confused - here it says the server will NOT be updated doing it this way but here it says to MAKE SURE and do it on the client to avoid the stuttering.
  • Here the suggestion is to “Make sure you’ve anchored the character…” but I don’t know if that is what I’m doing already by anchoring the HumanoidRootPart or something else. I tried anchoring all descendants of the player.character to check but that only makes things worse (character visual stays locked in one place).

I don’t think there are any other details that could help. I’ve used console output to verify this code is only running once, that the destination is correct (it does eventually get there), and things of that nature but happy to answer any questions to get un-stuck :slight_smile:

I am initiating the tween in RunService.Heartbeat so thought maybe it should use RunService.Stepped to avoid physics conflicts but that didn’t change anything :frowning:

Is anyone successfully tweening the player and could share their solution?

Or maybe there is a better way to do this? i.e. move the player slowly from one point to another? In my research, this is what TweenService is supposed to do but I’m not sure what is wrong and would take an alternative solution at this point.

It depends on what you Tween
In the post you have linked I was talking about a ServerObject

For example, there’s certain things you want to Tween only on the client and certain things you want to Tween only on the server.

If you want to tween the player camera, you do it from the Client.
If you want to let a player tween a part, you use RemoteEvents and create the Tween on the server and play it.

If you want to tween anything (bodyparts, camera) of a Player, do it on the client and it should automatically replicate on the Server.

The jittering is caused because of the Server doing the tween to the player, camera’s movement as well.

Hope this helps!

Thanks for the explanation, that helps.

But I’m not quite sure what you mean by this… could you clarify?

Because the Server is the one doing the Tween to the player, it jitters
Since the Server is central, and it has to replicate everything to everyone at once, its like letting someone else use your hand to write something on a paper
The client is much smoother since it’s you writing on your own paper

I hope that makes sense

It does. The script I’m using is running client-side… I tried both server and client-side with the same result (although marginally worse on server). The video in the original post is with client-side execution.

does the Tween play on the client

yes, you can see it in the video in the original post

That is, the tween does play on the client - it is doing so in the video and the video shows the glitching that the tween playing on the client is doing :slight_smile:

May I ask - have you implemented tweening the player?

I can replicate the problem using a new, empty baseplate. Here it is:
player-tween-jitter.rbxl (38.9 KB)

And for reference, here is the entirety of the implementation (not much to it)
Server sends remote event sent when player touches part:

local ReplicatedStorage 	= game:GetService("ReplicatedStorage")
local Players 				= game:GetService("Players")

local TweenPlayer 	= ReplicatedStorage:WaitForChild("TweenPlayer")

local Part = script.Parent

local DebouncePerPlayer = {}

Part.Touched:Connect(function(touched)
	local player = Players:GetPlayerFromCharacter(touched.Parent)
	if not player then return end

	if DebouncePerPlayer[player.UserId] then return end
	DebouncePerPlayer[player.UserId] = true

	TweenPlayer:FireClient(player)

	wait(5)
	DebouncePerPlayer[player.UserId] = nil
end)

Local script receives event and creates tween:

local ReplicatedStorage 	= game:GetService("ReplicatedStorage")
local Players 				= game:GetService("Players")
local TweenService			= game:GetService("TweenService")
local Debris				= game:GetService("Debris")

local TweenPlayer			= ReplicatedStorage:WaitForChild("TweenPlayer")


local function anchorForTween(anchored, hrp)
	for _, child in pairs(hrp:GetDescendants()) do
		if child:IsA("BasePart") then
			child.Anchored = anchored
		end
	end
end

TweenPlayer.OnClientEvent:Connect(function(internalDisc)
	local character = Players.LocalPlayer.Character
	local hrp = character:FindFirstChild("HumanoidRootPart")	

	anchorForTween(true, hrp)

	-- tween up and over
	local dest = CFrame.new(
		Vector3.new(hrp.CFrame.Position.X + 20, hrp.CFrame.Position.Y + 20, hrp.CFrame.Position.Z + 20),
		hrp.CFrame.LookVector
	)
	local tween = TweenService:Create(
		hrp,
		TweenInfo.new(3, Enum.EasingStyle.Quad),
		{ CFrame = dest }
	)

	tween.Completed:Connect(function()
		Debris:AddItem(tween)
		anchorForTween(true, hrp)

		print("made it")
	end)

	tween:Play()

end)

Result:

For potential future searchers,

Only anchor the humanoid root part!

@dthecoolest is magic

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.