Need help implementing FABRIK to rigged model

Hello everyone,

I’ve been trying to implement FABRIK to rigged models (like the rig models that you get from rig builder) for some time now but it really isn’t working. Here’s a video of my failure:

Code
-- getting run service for rendering every frame
local RUS = game:GetService("RunService")

-- subject to be ik'ed on
local Dummy = workspace.Dummy

-- start and end parts
local FixedStart = workspace.FixedStart
local EndPart = workspace.EndEffector

-- table of segments
local Segments = {Dummy.LeftUpperLeg, Dummy.LeftLowerLeg, Dummy.LeftFoot}
local StartSegment = Segments[1]
local EndSegment = Segments[#Segments]

-- joints
local Hip = Dummy.LeftUpperLeg.LeftHip
local Knee = Dummy.LeftLowerLeg.LeftKnee
local Ankle = Dummy.LeftFoot.LeftAnkle

-- constant basic c0s
local HipC0 = Hip.C0
local KneeC0 = Knee.C0
local AnkleC0 = Ankle.C0


-- lengths
local Lengths = {}

-- get the lengths between
local function GetDistances()
	for i = #Segments - 1, 1, -1 do
		local CurrentPart = Segments[i]
		local NextPart = Segments[i + 1]
		local CurrentJoint = CurrentPart:FindFirstChildOfClass("Motor6D")
		local NextJoint = NextPart:FindFirstChildOfClass("Motor6D")
		
		local Pc = CurrentJoint.C0 --* CurrentPart.CFrame
		local Pn = NextJoint.C0 --* NextPart.CFrame
		
		Lengths[i] = (Pn.Position - Pc.Position).Magnitude
	end
end


--// main/solving //--
local function Solve()
	EndSegment.Position = EndPart.Position
	for i = #Segments - 1, 1, -1 do
		local CurrentPart = Segments[i]
		local CurrentJoint = Segments[i]:FindFirstChildOfClass("Motor6D")
		
		local NextPart = Segments[i + 1]
		local NextJoint = Segments[i + 1]:FindFirstChildOfClass("Motor6D")
		
		local WPc = CurrentJoint.C0 * CFrame.Angles(NextJoint.C0.ZVector.X, NextJoint.C0.ZVector.Y, NextJoint.C0.ZVector.Z)
		local WPn = NextJoint.C0 --* NextPart.CFrame

		local VecBetween = (WPc.Position - WPn.Position)
		CurrentJoint.C0 = WPn + ( VecBetween.Unit ) * Lengths[i]
	end
	
	StartSegment.Position = FixedStart.Position
	for i = 2, #Segments, 1 do
		local CurrentPart = Segments[i]
		local CurrentJoint = Segments[i]:FindFirstChildOfClass("Motor6D")

		local NextPart = Segments[i - 1]
		local NextJoint = Segments[i - 1]:FindFirstChildOfClass("Motor6D")
		
		local WPc = CurrentJoint.C0 * CFrame.Angles(NextJoint.C0.ZVector.X, NextJoint.C0.ZVector.Y, NextJoint.C0.ZVector.Z)
		local WPn = NextJoint.C0 --* NextPart.CFrame
		
		local VecBetween = (WPc.Position - WPn.Position)
		CurrentJoint.C0 = WPn + ( VecBetween.Unit ) * Lengths[i - 1] 
	end
end

-- update function to be run every frame
local function Update(dt)
	-- go through the leg and solve for the  end effector
	Solve()
	
	
end

GetDistances()
-- connecting update function every rendered frame
RUS.Heartbeat:Connect(Update)

As you can see, the joints just move as they wish. I want to make them move like a person; they bend the joints to go to the position.

Am I changing the wrong values to make them move in this way? Or am I implementing FABRIK incorrectly to rigged models? (I’m not asking for an entire system to be made; I just want a step-by-step process on how to do this.) Thanks for your help.

p.s: I can’t respond quickly because I have to go now. I’ll get to the responses tomorrow. :slight_smile:

2 Likes