Hey all I was just wondering if there was anything I can do to make the movement of the legs any smoother or faster? In the the video that they look fine when just walking normally but when it turns you can see the disconnect from the body and the leg.
[Local Script]
I have a heartbeat loop for the player input and calling the update function, not much else in here
runService.RenderStepped:Connect(function(dt)
local mouseDelta = math.rad(userInput:GetMouseDelta().X) / 10
mouseDelta = math.clamp(mouseDelta, -0.15, 0.15)
origin.CFrame *= CFrame.Angles(0, -mouseDelta, 0)
velocity.x = 0
velocity.z = 0
if (getKey(Enum.KeyCode.W)) then
velocity.z = -SPEED
elseif (getKey(Enum.KeyCode.S)) then
velocity.z = SPEED
end
if (getKey(Enum.KeyCode.A)) then
velocity.x = -SPEED
elseif (getKey(Enum.KeyCode.D)) then
velocity.x = SPEED
end
local direction = Vector3.new(velocity.x, 0, velocity.z).Unit
if (direction ~= direction) then
direction = Vector3.new(0, 0, 0)
end
origin.CFrame *= CFrame.new(direction * SPEED)
for _, leg in pairs(legs) do
leg.update()
end
IK.updateRoot(origin, legs, originalHeight)
end)
[Module Script]
Checks the distance between the current leg position and the fixed “default” position that moves with the body, calls moveTarget() if distance is greater than a threshold and leg is grounded
function this.update()
updateFixedTarget()
if ((pFixed.Position - target).Magnitude >= STEP_DISTANCE) and (this.isGrounded()) then
moveTarget(pFixed.Position.Z - target.Z)
end
This is the function that moves the target the legs are pointing to, using a quad bezier to give the movement some curvature
local function moveTarget(offset)
for i = 0, 1, 0.1 do
target = utils.quadBezier(
i,
target,
target:Lerp(pFixed.Position, 0.5) + Vector3.new(0, 1, 0),
pFixed.Position + Vector3.new(0, 0, offset / 2)
)
task.wait()
end
end
Back to the update function, this is where it all actually happens. I basically make a right triangle between the legs and the target point. Then I use the side side side formula which is utils.SSS in here to get all the angles. From there, I just set the CFrames of the leg parts directly and that’s pretty much the main portion of how it works.
local sideC = (target - shoulder.Position).Magnitude
-- check if distance is too large, if it is then just point at the target
if (sideC >= size.Z * #this.segments) then
a.CFrame = CFrame.lookAt(shoulder.Position, target) * CFrame.new(0, 0, -sideA / 2)
b.CFrame = a.CFrame * CFrame.new(0, 0, -sideB)
return
end
local angleA = utils.SSS(sideB, sideC, sideA)
local angleC = utils.SSS(sideA, sideB, sideC)
a.CFrame = CFrame.lookAt(shoulder.Position, target)
* CFrame.Angles(angleA, 0, 0)
* CFrame.new(0, 0, -sideA / 2)
b.CFrame = a.CFrame
* CFrame.new(0, 0, -sideA / 2)
* CFrame.Angles(angleC, math.rad(180), 0)
* CFrame.new(0, 0, -sideB / 2)
end
I also feel that it’s worth mentioning that the loop seems to take a significant longer time when I am making drastic turns relative to just normal walking.
That is all and thank you