The problem I’m encountering is that when one or multiple legs are destroyed, the rig still remains upright instead of tipping or losing balance.
I haven’t found a solution yet because this issue is physics-based, and I believe the Humanoid’s HipHeight property will override any adjustments I try to make and I wasnt able to find any solutions on the creator hub.
For context, as you might have seen in the video, I’m testing IK control and creating procedural animations, which are working well so far. The final goal is to implement a balance system that allows the model to maintain stability and realistically fall over based on its own center of gravity.
Also this is the movement script im using to accomplish the leg movement.
local runService = game:GetService(“RunService”)
local enemy = script.Parent
local root = enemy:FindFirstChild(“HumanoidRootPart”)
local hum = enemy:FindFirstChildOfClass(“Humanoid”)
local target = workspace:FindFirstChild(“Target”)
local ikTargets = enemy:FindFirstChild(“IkTargets”)
local raycastParts = enemy:FindFirstChild(“RaycastParts”)
local alignOrientation = root:FindFirstChild(“AlignOrientation”)
local ProceduralModule = require(game.ReplicatedStorage:WaitForChild(“ProceduralModule”))
local RagdollModule = require(game.ReplicatedStorage:WaitForChild(“Ragdoll”))
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {enemy}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local legNames = {
“FrontLeftLeg”, “FrontRightLeg”, “MiddleLeftLeg”, “MiddleRightLeg”,
“BackLeftLeg”, “BackRightLeg”, “Back2LeftLeg”, “Back2RightLeg”
}
local legs = {}
for _, name in ipairs(legNames) do
local ikTarget = ikTargets:FindFirstChild(name .. “_IkTarget”)
local raycastPart = raycastParts:FindFirstChild(name .. “_RaycastPart”)
local ikControl = hum:FindFirstChild(name)
local pole = root:FindFirstChild(name .. “_Pole”)
if ikTarget and raycastPart and ikControl and pole then
local health = ikControl:FindFirstChild("Health")
if not health then
health = Instance.new("NumberValue")
health.Name = "Health"
health.Value = 100
health.Parent = ikControl
end
table.insert(legs, {
name = name,
ikTarget = ikTarget,
raycastPart = raycastPart,
ikControl = ikControl,
pole = pole,
enabled = true,
health = health,
})
ikControl.Pole = pole
end
end
coroutine.wrap(function()
while task.wait(0.25) do
if target and target:IsDescendantOf(workspace) then
hum:MoveTo(target.Position)
end
end
end)()
runService.Heartbeat:Connect(function()
local rayCast = workspace:Raycast(root.Position, -1000 * root.CFrame.UpVector, raycastParams)
if rayCast then
local floorRot = ProceduralModule:getRotationBetween(root.CFrame.UpVector, rayCast.Normal)
local floorCFrame = floorRot * CFrame.new(root.Position)
local dz = (root.Position.Z - target.Position.Z)
local dx = (root.Position.X - target.Position.X)
local angle = math.atan2(dx, dz)
if alignOrientation and alignOrientation.Enabled then
alignOrientation.CFrame = floorCFrame.Rotation * CFrame.fromOrientation(0, angle, 0)
end
end
end)
runService.Heartbeat:Connect(function()
local totalY, activeLegs = 0, 0
local lowestY = math.huge
local highestY = -math.huge
for _, leg in ipairs(legs) do
if leg.enabled then
local y = leg.ikTarget.Position.Y
totalY += y
activeLegs += 1
lowestY = math.min(lowestY, y)
highestY = math.max(highestY, y)
end
end
local align = root:FindFirstChild("StepAlign")
if align and activeLegs > 0 then
local avgY = totalY / activeLegs
local tiltAmount = (highestY - lowestY) / 4
align.Position = Vector3.new(root.Position.X, avgY + 3 - tiltAmount, root.Position.Z)
end
end)
local phaseToggle = false
coroutine.wrap(function()
while task.wait(0.2) do
local stepData = {
[false] = {
{“BackLeftLeg”, -1.5, -3.6, 2}, {“BackRightLeg”, -1.5, -4.2, 2.4},
{“Back2LeftLeg”, -1.5, -4, 1.6}, {“Back2RightLeg”, -1.5, -4.4, 2.2},
{“FrontLeftLeg”, -1.5, 4, 4}, {“FrontRightLeg”, -1.5, -3, 2.4},
{“MiddleLeftLeg”, -1.5, -2.4, 2}, {“MiddleRightLeg”,-1.5, 3, 3},
},
[true] = {
{“BackLeftLeg”, -1.5, 4, 3}, {“BackRightLeg”, -1.5, 4.2, 3.2},
{“Back2LeftLeg”, -1.5, 4.2, 3.2},{“Back2RightLeg”, -1.5, 4.5, 3.5},
{“FrontLeftLeg”, -1.5, -3.6, 2}, {“FrontRightLeg”, -1.5, 4, 3},
{“MiddleLeftLeg”, -1.5, 3, 3}, {“MiddleRightLeg”,-1.5, -2.4, 2.2},
}
}
for _, data in ipairs(stepData[phaseToggle]) do
local legName, yOffset, zOffset, forward = unpack(data)
for _, leg in ipairs(legs) do
if leg.name == legName and leg.enabled then
ProceduralModule:IkLegStep(leg.ikTarget, leg.raycastPart, root, yOffset, zOffset, forward, 0.05, raycastParams)
break
end
end
end
phaseToggle = not phaseToggle
end
end)()