Hi, I’m currently trying to set up a basic procedural animation system with IKControls, specifically for the walk cycle of a custom rig. The IKControls have been set up and the target positions do move.
However I want the left leg to wait until there is a certain distance between itself and the right leg, which it currently does. Sometimes.
The issue right now is that sometimes the leg movements “sync” back up and move at the same time, which I do not want and I’m not sure as to why it happens.
I have attached a gif of the issue, with both a circular path of movement and a linear path, and as you can see at times the two legs move at the same time. There’s also an issue where the legs snap from being straight to being bent, however that’s not my main concern at the moment and may just be due to the length of the model’s legs.
Here’s what I currently have.
--initialise the model and the parts needed for the script
local walker = script.Parent
local hum = walker["Humanoid"]
local root = walker["HumanoidRootPart"]
hum["Animator"]:LoadAnimation(walker["Animation"]):Play()
local targets = game.Workspace["targets"]
--the current target of the ik
local rightLegCurrentTarget = targets["RightIKTarget"]
local leftLegCurrentTarget = targets["LeftIKTarget"]
--just used to display the potential "future target" of the ik
local rightLegFutureTarget = targets["RightLegFutureTarget"]
local leftLegFutureTarget = targets["LeftLegFutureTarget"]
local rightLegIK = hum["RightLegIK"]
local leftLegIK = hum["LeftLegIK"]
--function used to quickly perform a raycast downwards to account for slopes.
local function castDownwards(org)
local dir = Vector3.new(0, -1, 0) * 25
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {walker, targets}
local result = game.Workspace:Raycast(org, dir, params)
if result then
return result
else
return nil
end
end
--the left leg's movement checks if rightUpdating is false, if so then it will move.
local rightUpdating = false
local leftUpdating = false
local rightLegLastTarget = rightLegCurrentTarget.CFrame
game:GetService("RunService").Stepped:Connect(function(dt)
local moveDist = script:GetAttribute("moveDistance")
--script to make the model follow the part
game.Workspace["follow"].CFrame = CFrame.new(20, 10, -20) * CFrame.new(math.cos(tick() * 0.8) * 20, 0, 0)
local followPos = game.Workspace["follow"].CFrame.Position
hum:Move((-root.CFrame.Position + followPos).Unit)
--right leg movement
local rightLegCast = castDownwards((root.CFrame * CFrame.new(1.5, 0, -moveDist / 2).Position))
if rightLegCast then
rightLegFutureTarget.CFrame = CFrame.new(rightLegCast.Position)--display the future position of the target
local dist = (rightLegCast.Position - rightLegCurrentTarget.Position).Magnitude
--checks the distance of its current target and the future target to see if it exceeds the required distance (in this case 8 units)
if dist >= moveDist then
rightUpdating = true
rightLegLastTarget = rightLegCurrentTarget.CFrame
rightLegCurrentTarget.CFrame = CFrame.new(rightLegCast.Position) * CFrame.new(0, 0.5, 0)
else
if rightUpdating and (rightLegCast.Position - rightLegLastTarget.Position).Magnitude >= moveDist then
-- if the target is within the radius then stop "updating" the right leg
-- the only problem with this is that this change basically occurs instantly, however the leg's aren't always synced so im not sure
rightUpdating = false
end
end
end
--left leg movement
local leftLegCast = castDownwards((root.CFrame * CFrame.new(-1.5, 0, -moveDist / 2).Position))
if leftLegCast then
leftLegFutureTarget.CFrame = CFrame.new(leftLegCast.Position)
local dist = (leftLegCast.Position - leftLegCurrentTarget.CFrame.Position).Magnitude
local distFromRight = ((leftLegCurrentTarget.CFrame * CFrame.new(2, 0, 0)).Position - rightLegCurrentTarget.CFrame.Position).Magnitude
--i just put an additional check on the left leg to see if the right leg isn't currently updating
if dist >= moveDist and not rightUpdating then
leftUpdating = true
leftLegCurrentTarget.CFrame = CFrame.new(leftLegCast.Position) * CFrame.new(0, 0.5, 0)-- * CFrame.new(0, dist / 20, 0)
end
end
end)
If anyone knows how I could fix this issue that would be appreciated.
Thanks!