Bones with different parent names don't animate in game, but do in editor

What do i want to achieve?

I'm creating a custom skinned mesh rig with lots of extra bones and i want it to support R15 animations.
Here is the bone hierarchy


RobloxStudioBeta_HiDYIvijfJ


What is the issue?

The bones with the same name as the R15 parts don't animate in game, BUT for some reason they do animate in the animation editor.

In editor:

In game:

As you can see some of the bones animate in game, but some don’t. The reason why some bones don’t animate is because their parent names aren’t the same as the R15 rig.


What solutions have i thought of so far?

I’ve tried renaming the parent names to the same names the R15 rig has like this:
image
This allows the animations to animate the bones, but it also results in very obvious issues

Ideally i should never have to rename the parent bones so i can keep their names unique.

Is there any way to make animations ignore the fact that the name of the parent bone is different from the R15 rig? This would solve all the issues and let me have a more advanced bone hierarchy while allowing me to play R15 animations

Alternative solutions:

  • Have a custom animation player like Moonlite but i have no experience with loading animations like this and i’m not sure if it would help.
  • Trick the animator into thinking the parent has the correct name? How?
1 Like

I’ve figured out a solution to this problem, but it’s not fantastic

The way i decided to solve this is by having 2 Root parts instead and have a script that switches the Motor6D’s of the character any time the animation is a custom one i uploaded.

This is how the character hierarchy looks like now:

R15 bones

Custom bones

This is the modulescript i created and placed in replicated storage
local Animate = {
	Root = nil,
	Humanoid = nil
}

function Animate.Init(Humanoid: Humanoid)
	Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
	Animate.Humanoid = Humanoid
end

local function switchMotor6D(Humanoid: Humanoid, NewRoot: Part)
	print("Switched")
	for _, Motor6D: Instance in pairs(Humanoid.Parent:GetDescendants()) do
		if not Motor6D:IsA("Motor6D") then continue end
		if Motor6D.Parent.Name == "HumanoidRootPart" then continue end
		print(Motor6D.Parent.Name)
		local Motor6D = Motor6D :: Motor6D
		
		Motor6D.Part0 = NewRoot
	end
end

local function getRoot(AnimID: number)
	local Root = Animate.Humanoid.Parent:FindFirstChild("R15Root")
	if AnimID > 1425511203 then
		Root = Animate.Humanoid.Parent:FindFirstChild("RootPart")
	end
	return Root
end

function Animate.AnimationStarted(Animation: Animation)
	local AnimID = tonumber(string.split(Animation.AnimationId, "=")[2])
	
	local NewRoot = getRoot(AnimID)
	if NewRoot ~= Animate.Root then
		switchMotor6D(Animate.Humanoid, NewRoot)
		Animate.Root = NewRoot
	end
end

return Animate

This is how i edited the Animate script
--line 0
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local pose = "Standing"

local Animate = require(game:GetService("ReplicatedStorage").Animate)
Animate.Init(Humanoid)

--line 503
function playAnimation(animName, transitionTime, humanoid)
	local idx = rollAnimation(animName)
	local anim = animTable[animName][idx].anim
	Animate.AnimationStarted(anim)

	switchToAnim(anim, animName, transitionTime, humanoid)
	currentlyPlayingEmote = false
end

This works but has a slight downside


The walk animation in this video is replaced by a custom one while the idle animation is default, resulting in a T-pose for a split second

3 Likes

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