Help with Inverse Kinematics

Hey, so I have an Inverse Kinematics script and I am trying to make it so the Head (Neck Motor6D) follow the TargetPart, the UpperTorso (Waist Motor6D) follow the Head and the LowerTorso (Root Motor6D) follow the UpperTorso. But it’s not working the way I want it to.

Problem:

Script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Target = workspace:WaitForChild("Target1234")
local Character = script.Parent
local HumRootPart = Character:WaitForChild("HumanoidRootPart")
local Neck = Character:WaitForChild("Head"):WaitForChild("Neck")
local Waist = Character:WaitForChild("UpperTorso"):WaitForChild("Waist")
local Root = Character:WaitForChild("LowerTorso"):WaitForChild("Root")
local WaistC0 = Waist.C0
local NeckC0 = Neck.C0
local UpperLength = math.abs(Neck.C1.Y) + math.abs(Waist.C0.Y)
local LowerLength = math.abs(Waist.C1.Y) + math.abs(Root.C0.Y) + math.abs(Root.C1.Y)

local solveModule = ReplicatedStorage:WaitForChild("SolveIK")
local solveIK = require(solveModule)

RunService.Heartbeat:Connect(function()
	local HumRootPartCFrame = HumRootPart.CFrame * NeckC0
	local TargetPosition = Target.Position	
	local planeCF, shoulderAngle, elbowAngle = solveIK(HumRootPartCFrame, TargetPosition, UpperLength, LowerLength)

	Neck.C0 = HumRootPart.CFrame:toObjectSpace(planeCF) * CFrame.Angles(shoulderAngle, 0, 0)
	Waist.C0 = WaistC0 * CFrame.Angles(elbowAngle, 0, 0)
end)

RunService.Stepped:Connect(function()
	Neck.Transform = CFrame.new()
	Waist.Transform = CFrame.new()
	Root.Transform = CFrame.new()
end)

Note: I am not good with manipulating Motor6Ds. Another thing is that I am trying to make a VR Script (All the other ones out there aren’t good in my opinion). Final thing, the ServerScript is located inside a dummy that is inside the workspace. Should look something like this (game.Workspace.Dummy.Script).

The head seems to have its “front surface” (the bottom of the head) following the point, so maybe try multiplying the neck angle by 90 degrees downwards. Maybe add this to the end of the line where you’re setting the neck’s C0 and mess around with the angle values.

* CFrame.Angles(90,0,0)

It still does not work. Same results.

use my CCDIK module. Makes IK easier and customizable to prevent the neck from snapping.

All the code that is needed:

Summary
--[[
    Testing with R15 Dummy
]]
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CCDIKController = require(ReplicatedStorage.Source.CCDIKController)

local dummy = workspace.DummyWaist
local leftTarget = workspace.SomeTarget

local dummyMotor6Ds = {}

local dummyDescendants = dummy:GetDescendants()
for _,descendant in pairs (dummyDescendants) do
    if descendant:IsA("Motor6D") then
        dummyMotor6Ds[descendant.Name] = descendant
    end
end

local root = dummyMotor6Ds["Root"]
local neck = dummyMotor6Ds["Neck"]
local waist = dummyMotor6Ds["Waist"]

local leftLeg = {waist,neck}

local leftLegController = CCDIKController.new(leftLeg)
leftLegController.UseLastMotor = true --only if one motor6D in the table

RunService.Heartbeat:Connect(function()
    local goal = leftTarget.Position
    leftLegController:CCDIKIterateOnce(goal)
end)

Test place with the waist for easy access:

TestPlace.rbxlx (946.6 KB)

1 Like

@dthecoolest, Hey thank you for you’re help and time. Although this will affect my VR Script heavily in a negative way because it doesn’t update (sometimes it does but it’s choppy) whenever the part is really close near the Head. And when it’s far away, it work’s perfectly fine and smooth. I’m assuming this is an easy fix since it probably has to do with some radius or tick thing. But I don’t know how to fix it. Any help or tips?

Problem:

After fiddling with you’re module script’s I got it to work. Thank you so much.