Help with foot placement script

I’m working on a foot placement script, but I can’t figure how to set the position of the legs, and they look really weird

Script;

local function ResolverIK(OrigenCF, Meta, L1, L2)
local Localizado = OrigenCF:PointToObjectSpace(Meta);
local UnidadLocalizada = Localizado.Unit;
local L3 = Localizado.Magnitude;
local Axis = Vector3.new(0, 0, -1):Cross(UnidadLocalizada);
local Angulo = math.acos(-UnidadLocalizada.Z);
local Angulo2 = math.acos(-UnidadLocalizada.Y);
local PlanoCF = OrigenCF*CFrame.fromAxisAngle(Axis, Angulo);

if L3 < math.max(L2, L1)-math.min(L2, L1) then
      return PlanoCF*CFrame.new(0, 0, math.max(L2, L1)-math.min(L2, L1)), -math.pi/2, math.pi;
elseif L3 > L1+L2 then
      return PlanoCF, math.pi/2, 0;
else
local A1 = -math.acos((-(L2*L2)+(L1*L1)+(L3*L3))/(2*L1*L3));
local A2 = math.acos(((L2*L2)-(L1*L1)+(L3*L3))/(2*L2*L3));

      return PlanoCF, A1+math.pi/2, A2+A1;
    end
end

local function R15IK(Shoulder, Elbow, Meta, Valor_C0, C0)
local UpperArm = Elbow.Part0;
local LowerArm = Elbow.Part1;
local UpperTorsoCF = Shoulder.Part0.CFrame;
local R0, R1 = UpperArm.Size.Y-.25, LowerArm.Size.Y-.25;
local Plano, ShoulderAngulo, ElbowAngulo = ResolverIK(UpperTorsoCF*Valor_C0, Meta, R0, R1);

      Shoulder.C0 = UpperTorsoCF:ToObjectSpace(Plano)*CFrame.Angles(ShoulderAngulo, 0, 0);
      Elbow.C0 = C0*CFrame.Angles(ElbowAngulo, 0, 0);
end

local Psj = script.Parent;

local Hip = Psj:WaitForChild("RightUpperLeg").RightHip;
local Elbow = Psj:WaitForChild("RightLowerLeg").RightKnee;

local Hip2 = Psj:WaitForChild("LeftUpperLeg").LeftHip;
local Knee = Psj:WaitForChild("LeftLowerLeg").LeftKnee;

local C0 = Elbow.C0;
local C02 = Knee.C0;

local Valor_C0 = CFrame.new(Hip.C0.p);
local Valor_C02 = CFrame.new(Hip2.C0.p);

local HRP = Psj.PrimaryPart;

while wait() do
if math.abs(HRP.Velocity.X) > 0 then
local Rayo = Ray.new(Vector3.new(HRP.Position.X, HRP.Position.Y, HRP.Position.Z)+Hip.C0.p+Psj.Humanoid.MoveDirection, Vector3.new(0, -9999, 0));
local _, Posicion = workspace:FindPartOnRayWithIgnoreList(Rayo, {Psj});

local Rayo2 = Ray.new(Vector3.new(HRP.Position.X, HRP.Position.Y, HRP.Position.Z)+Hip2.C0.p+Psj.Humanoid.MoveDirection, Vector3.new(0, -9999, 0));
local _, Posicion2 = workspace:FindPartOnRayWithIgnoreList(Rayo2, {Psj});

	    R15IK(Hip, Elbow, Posicion, Valor_C0, C0);
	    R15IK(Hip2, Knee, Posicion2, Valor_C02, C02);
    end
end

Video;

4 Likes

@x_o used to have a place for IK foot placement for R6 characters. I can’t find it anymore, but here are some tips along with some code that I based off the walk cycle she had.

  1. The walk cycle should be relative to the player’s torso. So you shouldn’t use non-transformed vectors. Instead use CFrames converted to world space, then convert to position.
  2. Once you have the walk cycle position you should raycast. This is what will give you the actual IK feel.
  3. Movement direction should be gradually interpolated to. So even though you are using object space vectors converted to world space you want them to gradually shift as you character turns. Otherwise your legs will look very rigid.

Anyways, here’s the code. Hopefully you can dissect it for more of the nitty gritty answers.

IKFoot.rbxl (28.7 KB)

Note that you’ll need to upload and update the stiff legs animation which is in the dummy character.

http://doy2mn9upadnk.cloudfront.net/uploads/default/original/4X/e/d/d/edda1f57b755013c292c5c0bd3d67b5f30ba2d87.mp4

49 Likes

I have always needed something like this. This is great. Although I have some weird issues with it though:

2 Likes

Have you uploaded and updated the stiff leg animation? When I test with it disabled it looks exactly like the gif you posted.

This GIF was before I uploaded it however I just re-uploaded the animation and it still looks a little funky.

Here is what it looks like now: https://gyazo.com/a3e5c5d7d9c7c6fd04392d974e03c1e5

Yep, that’s what it’s suppose to look like. You can interpolate the legs to a more natural idle state when the character isn’t moving or in whatever condition you so choose. When I put that together my intention wasn’t to make the perfect foot placement IK, just something to test and play around with.

1 Like

Would you mind adding comments explaining what’s happening in the FootPlant object?
It’s hard to parse what the steps you’re taking are and for what reason
Example:
local desiredPosition = (CFrame.new(ground, ground + self._direction) * CFrame.Angles(-self["_"..key], 0, 0) * CFrame.new(0, 0, -height/2)).p
I understand that you’re making the desired vec3 for the current leg, and rotating by -math.pi on the x axis for some reason if it’s the right leg, but why?

After some messing around with the very helpful debug drawing library you included. I now understand what you’re doing. The points chosen to cast rays to two points that revolve in a circle around the player’s ground position and rotate based on horizontal velocity.

Don’t know why I never thought of something like this haha.

The solution I use for my footplanting in “eg” is kinda ugly by comparison, checking if the average position of the two legs is going to be behind the character by the time the next foot plant would be finished, and that the opposite leg is planted before starting a step tween to move to a predicted next foot position based on current velocity.

Though the nice thing about my solution is that it allows for an arbitrary (even) number of legs. (I don’t have a recording of this right now)

I’ll clean up my implementation a bit and post it here tomorrow.

17 Likes

Sorry to bring this thread back but here’s the foot plant place by x_o

4 Likes

Thank you for the help with footplanting ive benn struggling with this for along time now but i have a issue and cant solve it. When i climb up a ladder with this script it glitches out and the everything below the torso dissapears.How do i fix this?

Note:

this only happens when using the stiff leg animation and sprinting and in first person as im using this for a fps game

also how would i replicate this to the server

The server wouldn’t see the replicated animations…

However, you should use remote events so that all the clients update the player’s animations.

Updating the player animations in a server script would ruin the player’s animation because there would be animation overlap seen on the client’s environment.

Within EgoMoose’s FootPlant module, there was an unhandled SolveIK case which causes a huge footplanting bug - which is sometimes triggered when a player walks through a meshpart that is CanCollide = false (and a few other scenarios). This bug would cause the player to go under the map.

I modified the FootPlant module so that the (l3 < math.max(l2, l3) - math.min(l2, l1)) case is handled - which fixes the bug.

Here is a link to the updated place:
IKFoot (1).rbxl (31.3 KB)

(Egomoose’s IK footplanting modified) - Even though you might not find any immediate differences between the original and the modified place, the modified place handles another SolveIK case which happens to fix a few rare bugs.

12 Likes