Issue with my Inverse Kinematics script


I decided to try to make an inverse kinematics script for the first time. I’m having an issue where when the Goal gets too close to the Start, the script bugs out. It looks like the end of the Arm isn’t always touching the Goal for some reason and I’m not sure why.

local Segments = {
	[1] = workspace:WaitForChild("Part1"),
	[2] = workspace:WaitForChild("Part2"),
	[3] = workspace:WaitForChild("Part3"),
	[4] = workspace:WaitForChild("Part4")

local Start = workspace:WaitForChild("Point1")
local End = workspace:WaitForChild("Point2")

local function GetHead(Segment) -- Gets the end of a segment
	return Segment.Position + (Segment.CFrame.LookVector * (Segment.Size.Z / 2))

local function GetTail(Segment) -- Gets the start of a segment
	return Segment.Position - (Segment.CFrame.LookVector * (Segment.Size.Z / 2))

local function MoveSegment(Segment, Position) -- Move a segments head to a position
	Segment.CFrame = CFrame.lookAt(Segment.Position, Position)
	Segment.CFrame *=, 0, -(Position - GetHead(Segment)).Magnitude) 

local function MoveArm()
	for x=1, 5 do
		MoveSegment(Segments[4], End.Position)
		MoveSegment(Segments[3], GetTail(Segments[4]))
		MoveSegment(Segments[2], GetTail(Segments[3]))
		MoveSegment(Segments[1], GetTail(Segments[2]))
		-- Lock arm to start
		local Offset = (GetTail(Segments[1]) - Start.Position)

		for _,v in pairs(Segments) do
			v.Position -= Offset

while wait(.2) do

remove that.

Try :Lerping the CFrame instead of setting it directly.

The inner for loop is just to shift the arm back so that the arm is always touching the start. What would lerping do differently for this?

It would make it flexible so that two of the joints do not interfere and conflict. You would simply do myCFrame = myCFrame:Lerp(targetCFrame, 0.5) and change the 0.5 to a larger or smaller number depending on how flexible you want it.

I figured it out.

In the first line of MoveSegment I had:
Segment.CFrame = CFrame.lookAt(Segment.Position, Position)

However I needed:
Segment.CFrame = CFrame.lookAt(GetTail(Segment), Position)

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