Inverse Kinematics for Tripod

One more thing. How would I make the targets move with the tripod As I working on a ai so how would I make the tripods foot move like in this video EZ Fabrik IK (v1.3) - Inverse Kinematics Intended for any Motor6d Rig
I am based the walk to look like this

That’s going to be a bit more complicated. Personally I use iGottics method of moving the target position in a circle while raycasting to detect the floor position. You can find it over here:

Edit: another method you can use is this IK method from Swordphin123

I believe the method is the same as this video made from codedeer

when in doubt steal from unity :wink:

But I find the steps hard to follow so I used IGottics method. IDK both should work.

2 Likes

So I Looked over the code and I noticed that I am going to have to change many things. Now the Tripod doesn’t have any hip motors so what should I do?

	["rightLeg"] = {
		["CurrentCycle"] = 0,
		["LimbChain"] = rightLegChain,
		["HipAttachment"]= rightHipAttachment,
		["FootAttachment"] = rightStepAttachment,
	},

	["leftLeg"] = {
		["CurrentCycle"] = math.pi,
		["LimbChain"] =leftLegChain,
		["HipAttachment"]= leftHipAttachment,
		["FootAttachment"] = leftStepAttachment,
	}
}

Oh, the hip motor in the procedural animator script refers to the Motor6D that is connected from the HumanoidRootPart to the rig with the part0 being the humanoid root part and the part1 being connected to the first thing to the rig which in my case was the hip.

For the R15 dummy it will be the Root Motor6D.

And the hip attachment just controls the position where the foot detection system will start raycasting from in order to detect the floor.

I chose to use attachments because well they are easily debuggable visually and controllable. But yeah hope this clears up the terminology I used when making the procedural animator script. For more notes, you can look into the original script source which I copied took inspiration from which is the R15 foot planting resource. You will notice most of the things like variables for the RootMotor6D are the same.

1 Like

Ah Ok, So I just added a Hip Motor to the humanoid root part to the torso base, were the other motors for the legs are. Would I put this Procedural code in Serverscriptservice and separate from the muiti chain?

Well, the procedural animation code is a module script so it can be wherever however the multichain script has to have access to this object class as in order to create the object it requires the LimbChain object as noticed in the dictionary used to construct the legs.

["rightLeg"] = {
		["CurrentCycle"] = 0,
		["LimbChain"] = rightLegChain,
		["HipAttachment"]= rightHipAttachment,
		["FootAttachment"] = rightStepAttachment,
	},
1 Like

Its not working, I did some test, changed were the script was from the script service to the tripod model itself. I checked the output but there was no error, the inverse kinematics still work fine though. TripodTest.rbxl (502.7 KB) Wait Dont I need to weld the targets to the Main Torso or legs?

I’m guessing you need to animate it in a heartbeat loop

local RunService = game:GetService("RunService")
 
local tripod = proceduralAnimator.new()-- create it
RunService.Heartbeat:Connect(function(step)
ProceduralAnimatorClass:Animate(step)
end)
1 Like

Ok Now I am completely lost. When you mean Animate it do you mean like animate it though animation editor as I know that you can do that. If you have the save for the procedural mech? I can maybe reverse engineer it for my tripod.

Sorry, by animating I meant the procedural animation with my method of using a script to move the target points in a circle for the inverse kinematics script to follow and also I’m not planning to open-source my current procedural mech.

I believe the procedural animator above in the cool creations showcase I gave should be enough to work from, or maybe you should directly look at the R15 procedural animation resource for notes then reverse engineer from there like I have before. It was specifically in this post where I took notes of the target points the inverse kinematics is trying to reach the goal towards where I recorded a video of what the procedural animation script is actually doing, moving the red target in a circle which the inverse kinematics will then follow.

1 Like

Alright thanks. I am going to read through the ik script in the foot planting to get a better understanding. I still very new to scripting so that’s why I been asking many questions and probably dumb ones.

1 Like

I reamber that you told me that the FabIk

seems like my initial method didn’t work for really long legs.

Why is that the case?. Also With your CCDIK you been working on, what would be new added that’s is different to the your current Fabik. Also the foot of the tripods are not moving. I checked if the were some how welded some how. but nop just to the foot part itself.
Edit: I just check and the foot orientation is 0,0,0

Oh Initially I believed this section of the code was wrong for finding a vector that goes from the one motor to the other. I think it’s more reliable to work with the joint in world terms instead by multiplying the motor6d Part0 CFrame with the C0.

wrong code
function LimbChain.JointOneToTwoVector(motorOne, motorTwo)
    -- Check if its a motor6d
    if motorOne:IsA("Motor6D") and motorTwo:IsA("Motor6D") then
        local vecOne = motorOne.C1.Position
        local vecTwo = motorTwo.C0.Position
        local combinedVector = vecTwo - vecOne
        return combinedVector
    else
        return "Error: motor 6ds are not inserted in the function"
    end
end

Honestly I think you should just use my current implementation the the CCDIK ik as it uses a complete different method to rotate the limb which is not dependent on the orientation being (0,0,0) which the Fabric algorithm does. This is because I found out how to properly obtain the rotation CFrame between two vectors from EgoMoose’s tutorial.

1 Like

I was doing some test and found this quite funny. https://i.gyazo.com/cdbfc86db9a27af3700bcf033af96868.mp4

How Would I do the Foot placing system, on my tripod? As the MultiChain and the mech constraint Test are both written diffently.
Ok So I just added it to the script and changed thing around. Still would not work, but the IK still works and no errors in the output.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

--Modules required
local IKControllerPointer = ReplicatedStorage.Source.LimbChain
local LimbChain = require(IKControllerPointer)

--Left leg chain motors
local tripod = workspace.Tripod

local modelMotor6Ds = {}

local modelDescendants = tripod:GetDescendants()
for _,descendant in pairs (modelDescendants) do
	if descendant:IsA("Motor6D") then
		modelMotor6Ds[descendant.Name] = descendant
	end
end

--now you can index the Motor 6d's by name through the dictionary obtained
--Get the motors of the left leg chain
local lUpperLegMotor = modelMotor6Ds["LUpperLeg"]
local lLowerLegMotor = modelMotor6Ds["LLowerLeg"]
local lfoot = modelMotor6Ds["LFoot"]

--Get the motors of the right leg chain
local rUpperLegMotor = modelMotor6Ds["RUpperLeg"]
local rLowerLegMotor = modelMotor6Ds["RLowerLeg"]
local rfoot = modelMotor6Ds["RFoot"]

--Get the motors of the back leg chain
local bUpperLegMotor = modelMotor6Ds["BUpperLeg"]
local bLowerLegMotor = modelMotor6Ds["BLowerLeg"]
local bfoot = modelMotor6Ds["BFoot"]

--Create the left leg chain
local leftLegMotorTable = {lUpperLegMotor,lLowerLegMotor,lfoot}

local leftLegChain = LimbChain.new(leftLegMotorTable)

--create the right leg chain
local rightLegMotorTable = {rUpperLegMotor,rLowerLegMotor,rfoot}
local rightLegChain = LimbChain.new(rightLegMotorTable)

--Create the back leg chain
local backLegMotorTable = {bUpperLegMotor,bLowerLegMotor,bfoot}
local backLegChain = LimbChain.new(backLegMotorTable)

--Foot placement system
local footParams = RaycastParams.new()
local ignoreParts = workspace:WaitForChild("RayFilterFolder")
footParams.FilterDescendantsInstances = {tripod,ignoreParts}

leftLegChain.FootPlacementRaycastParams = footParams
leftLegChain.LengthToFloor = 80

local down = Vector3.new(0,-80,0)

RunService.Heartbeat:Connect(function()
	
	local goalPosition = workspace.BigLTarget.Position
	local goalRightPosition = workspace.BigRTarget.Position
	local goalLeftPosition = workspace.BigRTarget.Position
	local rayResult = workspace:Raycast(goalPosition,down,footParams)
	if rayResult then
		leftLegChain:IterateOnce(rayResult.Position,0.1)
	end
	leftLegChain:UpdateMotors()

	local leftTarget = workspace.BigLTarget.Position
	local rightTarget = workspace.BigRTarget.Position
	local backTarget = workspace.BigBTarget.Position

	leftLegChain:IterateOnce(leftTarget,0.1)
	leftLegChain:UpdateMotors()

	backLegChain:IterateOnce(backTarget,0.1)
	backLegChain:UpdateMotors()

	rightLegChain:IterateOnce(rightTarget,0.1)
	rightLegChain:UpdateMotors()

end)

TripodTest.rbxl (1.1 MB)

Ok for the foot placement system, you gotta add the bool option to the constructor.

local leftLegChain = LimbChain.new(leftLegMotors,true)

Then you will have to add attachments to the object

--Get all the attachments in the left foot
leftLegChain.FootBottomAttachment = lowerBody.LeftLeg.LFeet.FootBottom
leftLegChain.FootBottomRightAttachment = lowerBody.LeftLeg.LFeet.FootBottomRight

The raycasting will begin at these two points and the foot will orient to the normal accordingly. For the other posts that you deleted with the procedural animator make sure you understand both OOP and module scripts because well the code I gave is mostly experimental and not complete so you can’t execute it simple with just one function.

1 Like

When you talking about attachment are you meaning about ball sockets?
Oh wait nvm as it’s already motor 6d connected. Oh and I think I understand stand why there is an attachment there as it is were the ray casting starts from

Could you explain to me why both feet(or for me three feet) have all the attachments to the left leg. I have notice a theme with the left leg. Is the left leg just a parent starting place for the script to properly work?
Edit: So I did it and it worked normally. So I though i could put the attachments to the proper foot. I edited the script. I checked if there were any errors and there were not and the left foot is twisted backwards. Anything I should do?

--Foot placement system
local footParams = RaycastParams.new()
local ignoreParts = workspace:WaitForChild("RayFilterFolder")
footParams.FilterDescendantsInstances = {tripod,ignoreParts}

leftLegChain.FootPlacementRaycastParams = footParams
leftLegChain.LengthToFloor = 80

leftLegChain.FootBottomAttachment = tripod.LLeg.LFoot.FootBottom
leftLegChain.FootBottomRightAttachment = tripod.RLeg.RFoot.FootBottomRight
leftLegChain.FootBottomBackAttachment = tripod.BLeg.BFoot.FootBottomBack

local rightLegChain = LimbChain.new(rightLegMotorTable,true)
local backLegChain = LimbChain.new(backLegMotorTable,true)

TripodTest.rbxl (1.1 MB)

Oh that’s actually a typo error caused from me copy and pasting the leg code and forgetting to change the attachments.

And honestly for the foot placement system I would suggest entirely rewriting the foot placement code, using two attachments isn’t accurate enough to get the surface normal of the floor. I would suggest using a three attachment system to get the plane surface of the floor like how easy entities by QuasiDuck does it. You can fork the edits in LimbChain :UpdateFootMotors function which controls the last motor and see how it works.

1 Like

Hello, I am Back.
So With the New CCDIK, I know that now I can have them orientated any way. Any Things I know. Like with the Motors and foot attachments? I know that I am going to have to make some modifications to the Multichain tripod Script.