Unsynced unicycle animation

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want my Idle animation to sync between the humanoid and the Unicycle
    i just need to know what im doing wrong since ive tried multiple times for like 4 hours
  2. What is the issue? Include screenshots / videos if possible!
    Both the animations start at the same time and they work fine in animation editor , But are somehow unsynced when i add them to a player character
External Media External Media

3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

I added the unicycle to the rig via a server script
And i added the animation via a local script in StarterPlayerScripts

-- This is an example Lua code block

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

local function setupCharacter(character)
	local humanoid = character:WaitForChild("Humanoid")
	local rootPart = character:WaitForChild("HumanoidRootPart")
	humanoid.HipHeight = 2.45
    character:GetChildren().Massless = true
	humanoid:ChangeState(Enum.HumanoidStateType.Physics) 

	local unicycle = ReplicatedStorage:WaitForChild("UnicycleRig"):Clone()
	unicycle.Parent = character

	local motor = Instance.new("Motor6D")
	motor.Name = "RootPart"
	motor.Part0 = rootPart
	motor.Part1 = unicycle:WaitForChild("RootPart")
	motor.C1 = CFrame.new(0, 2.4, 0) * CFrame.Angles(0, math.rad(180), 0)
	motor.Parent = rootPart
end

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(setupCharacter)
end)

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

local player = Players.LocalPlayer

local AnimationIds = {
	Idle = "rbxassetid://88503029816870",
	Move = "rbxassetid://111571310807043",
}

local humanTrack, unicycleTrack
local currentState = "Idle"


local function setupAnimations()
	local character = player.Character
	if not character then return end

	local humanoid = character:WaitForChild("Humanoid")
	local animator = humanoid:FindFirstChildOfClass("Animator") or humanoid:WaitForChild("Animator")
	local unicycle = character:WaitForChild("UnicycleRig")
	local unicycleAnimator = unicycle:WaitForChild("AnimationController"):WaitForChild("Animator")

	for name, id in pairs(AnimationIds) do
		local humanAnim = Instance.new("Animation")
		humanAnim.AnimationId = id
		humanTrack = animator:LoadAnimation(humanAnim)

		local unicycleAnim = Instance.new("Animation")
		unicycleAnim.AnimationId = id
		unicycleTrack = unicycleAnimator:LoadAnimation(unicycleAnim)

		
		humanTrack.Priority = Enum.AnimationPriority.Movement
		unicycleTrack.Priority = Enum.AnimationPriority.Movement
	end
end


local function playAnimation(animName)
	local character = player.Character
	if not character then return end

	local humanoid = character:WaitForChild("Humanoid")
	local animator = humanoid:FindFirstChildOfClass("Animator") or humanoid:WaitForChild("Animator")
	local unicycle = character:WaitForChild("UnicycleRig")
	local unicycleAnimator = unicycle:WaitForChild("AnimationController"):WaitForChild("Animator")


	local humanAnim = Instance.new("Animation")
	humanAnim.AnimationId = AnimationIds[animName]

	local unicycleAnim = Instance.new("Animation")
	unicycleAnim.AnimationId = AnimationIds[animName]


	if humanTrack then humanTrack:Stop() end
	if unicycleTrack then unicycleTrack:Stop() end

	
	unicycleTrack = unicycleAnimator:LoadAnimation(unicycleAnim)
	humanTrack = animator:LoadAnimation(humanAnim)



	humanTrack.Priority = Enum.AnimationPriority.Movement
	unicycleTrack.Priority = Enum.AnimationPriority.Movement

	print("[Human] Playing Animation: " .. animName .. " Track length: " .. humanTrack.Length)
	print("[Unicycle] Playing Animation: " .. animName .. " Track length: " .. unicycleTrack.Length)


	unicycleTrack:Play()
	humanTrack:Play()
	

	task.wait(0.1)  
	humanTrack.TimePosition = 0
	unicycleTrack.TimePosition = 0
end


UserInputService.InputBegan:Connect(function(input, processed)
	if processed then return end
	if input.KeyCode == Enum.KeyCode.W or input.KeyCode == Enum.KeyCode.A or input.KeyCode == Enum.KeyCode.S or input.KeyCode == Enum.KeyCode.D then
		if currentState ~= "Move" then
			currentState = "Move"
			playAnimation("Move")
		end
	end
end)


UserInputService.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.W or input.KeyCode == Enum.KeyCode.A or input.KeyCode == Enum.KeyCode.S or input.KeyCode == Enum.KeyCode.D then
		task.wait(0.1)
		if not (UserInputService:IsKeyDown(Enum.KeyCode.W) or UserInputService:IsKeyDown(Enum.KeyCode.A) or UserInputService:IsKeyDown(Enum.KeyCode.S) or UserInputService:IsKeyDown(Enum.KeyCode.D)) then
			if currentState ~= "Idle" then
				currentState = "Idle"
				playAnimation("Idle")
			end
		end
	end
end)


player.CharacterAdded:Connect(function()
	currentState = "Idle"
	setupAnimations()
	task.wait(0.1)
	playAnimation("Idle")
end)

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

Something you have to ensure when combining animations with external object is that the Motor6Ds have to have the exact same Parent, CFrames and Properties (Name) to avoid issues.

Are you sure these requirements are met?

Yes they are i also tried preloading the animations and syncing them
But even when they start at the same time they still are dysynced
one thing im suspecting is causing the issue is rotating the unicycle 180 degrees.
i rotated it because it wasnt aligned with the character

wait, can you show your animation dummies hierachy? and secondly, did you animate it with its offset? ; (C1 OR C0 ~= zero)

From what you’ve done, I suggest you read this post abit, because I’m not really that confident that you should be doing that, its offset should be manually done within the animation. I’ve personally made Animated Tools and I’ve never manually offsetted the C1.


So your problem is in your script, this is how it should look like,

local function setupCharacter(character)
	local humanoid = character:WaitForChild("Humanoid")
	local rootPart = character:WaitForChild("HumanoidRootPart")

	humanoid.HipHeight = 2.45
	character:GetChildren().Massless = true
	humanoid:ChangeState(Enum.HumanoidStateType.Physics) 

	local unicycle = ReplicatedStorage:WaitForChild("UnicycleRig"):Clone()
	local targetPart = unicycle.RootPart -- anything cloned from replicated store is already "replicated" or there.

	local motor = Instance.new("Motor6D")
	motor.Name = "UnicycleWeld" -- are you sure you want to name it RootPart?
	motor.Part0 = rootPart
	motor.Part1 = targetPart
	motor.Parent = rootPart

	unicycle.Parent = character -- putting it at the end here for a smooth transition
end

So i kindly ask that you show the "UnicycleRig"'s Hierarchy?.

image

The issue is from the animation , i found this out by trying other animations as the idle but they worked perfectly fine . i think the reason is the way my animator set it up
in unicycle animations its only the wheel and pedals moving
but in the humanoid idle anim it moves the unicycle aswell which isnt the case for the other animation. i will still look around

I found the solution! as i suspected the rotation of the rig was the issue

1 Like