Issue with my Inverse Kinematics script

Hi.

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))
end

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

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

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
		end
	end
end

while wait(.2) do
	MoveArm()
end

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)

https://i.gyazo.com/003dd5ae356b9c1ff26e90d3d4eb1854.mp4

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