Sure, here is a title for the code you sent: Enhanced Realistic Character Physics and Balancing ```lua local character = script.Parent local humanoid = character:WaitForChild("Humanoid") local rootPart = character:WaitForChild("HumanoidRootPart") local upperTorso = character:FindFirstChild("UpperTorso") local lowerTorso = character:FindFirstChild("LowerTorso") local rightHand = character:FindFirstChild("RightHand") local leftHand = character:FindFirstChild("LeftHand") local head = character:FindFirstChild("Head") local userInputService = game:GetService("UserInputService") local runService = game:GetService("RunService") local physicsService = game:GetService("PhysicsService") humanoid.BreakJointsOnDeath = false humanoid.RequiresNeck = false -- Collision Group Constants local LEFT_LEG_GROUP = "RagdollLeftLeg" local RIGHT_LEG_GROUP = "RagdollRightLeg" local DEFAULT_COLLISION_GROUP_NAME = "Default" -- Configurable Stiffness (Reduced for Realism) local LEG_STIFFNESS_FACTOR = 0.45 -- More flex, less robotic local ARM_STIFFNESS_FACTOR = 3.0 -- Slightly more relaxed arms -- State Variables & Constants local isRagdolled = false local jointConstraints = {} local physicsConstraints = {} local originalCollisions = {} local ragdollAttachments = {} local stepConnection = nil -- Enhanced Active Balancing State local steppingFootName = nil local stepTargetPosition = nil local stepStartPosition = nil local stepDistance = 0 local stepCooldown = 0 local stepProgress = 0 local lastSteppedFoot = "RightFoot" local isStumbling = false local stumbleSeverity = 0 local currentStepDuration = 0.1 local currentBalanceDirectionXZ = nil local lastLeanForward = 0 local lastLeanRight = 0 local lastGroundNormal = Vector3.yAxis local lastLeanVelocity = Vector2.zero local needsRecoveryStep = false local predictiveStepTrigger = false -- New: Predictive stepping local balanceRecoveryMomentum = Vector3.zero -- New: Momentum for recovery local torsoSwayPhase = 0 -- New: For natural torso oscillation local baseSwayAmplitude = 0.015 -- Base torso sway even when balanced -- Shot Reaction State local isShotReacting = false local shotReactTimer = 0 local SHOT_REACTION_DURATION = 0.55 -- Slightly faster reaction local SHOT_IMPULSE_MAGNITUDE = 70 -- Increased impulse -- Dynamic Parameter Ranges (Realism Focused) local DYNAMIC_STEP_DURATION_MIN = 0.22 -- Slightly slower min local DYNAMIC_STEP_DURATION_MAX = 0.60 -- Slightly slower max local DYNAMIC_STEP_COOLDOWN_MIN = 0.12 -- Slightly slower recovery local DYNAMIC_STEP_COOLDOWN_MAX = 0.40 -- Slightly slower max cooldown local DYNAMIC_STANCE_WIDTH_MIN = 0.75 -- Slightly narrower min stance local DYNAMIC_STANCE_WIDTH_MAX = 1.70 -- Slightly narrower max stance local RECOVERY_STEP_COOLDOWN_MULTIPLIER = 0.40 -- Slightly slower recovery steps -- Timing & Step Constants (Realistic Gait) local STEP_COMPLETION_DISTANCE = 0.09 -- Tighter for precision local STEP_MAX_REACH = 2.7 -- Slightly reduced max reach local GAIT_ANGLE_RAD = math.rad(2.5) -- Slightly narrower gait local STEP_OBSTACLE_CLEARANCE_HEIGHT = 0.18 -- Slightly lower clearance local STEP_OBSTACLE_CHECK_DISTANCE = 0.30 -- Slightly shorter check local GROUND_RAYCAST_DISTANCE = 12 -- Shorter raycast -- Balancing Thresholds & Prediction (More Responsive) local BALANCE_LeanThreshold_FB = 0.13 -- More sensitive forward/back local BALANCE_LeanThreshold_LR = 0.07 -- More sensitive lateral local BALANCE_VelocityPredictionFactor = 0.40 -- Stronger velocity influence local BALANCE_StepDistanceFactor = 1.30 -- Longer steps for recovery local STUMBLE_THRESHOLD = 0.40 -- Earlier stumble detection local RECOVERY_STEP_STUMBLE_THRESHOLD = 0.16 -- Earlier recovery steps local DOMINANT_LEAN_RATIO_THRESHOLD = 1.4 -- More dynamic lean priority local MAX_DIRECTION_CHANGE_ANGLE_RAD = math.rad(80) -- Slightly tighter direction changes -- Force & Responsiveness (Realistic Forces) local BALANCE_StepForce = 12000 -- Slightly reduced step force local BALANCE_StepResponsiveness = 85 -- Slightly less responsive stepping -- Stance & Lift Parameters (Natural Stance) local BALANCE_LiftHeight_Base = 0.11 -- Slightly lower base lift local BALANCE_LiftHeight_ScalePerStud = 0.055 local BALANCE_LiftHeight_MaxCap = 0.55 -- Slightly lower cap local STUMBLE_LIFT_MULTIPLIER = 3.2 -- Less exaggerated stumble lift -- Smoothing, Damping, and Stiffness (Smoother Motion) local TORSO_LERP_BASE = 0.07 -- Smoother base torso movement local TORSO_LERP_AGGRESSION = 0.28 -- Slightly less aggressive correction local TORSO_RESPONSIVENESS_LEAN_VEL_FACTOR = 110.0 -- Slightly less reactive to velocity local ARM_LERP_FACTOR = 0.11 -- Slightly slower arm response local ARM_SWING_INTENSITY = 3.8 -- Slightly weaker arm swing local STUMBLE_ARM_SWING_MULTIPLIER = 1.2 -- Less dramatic stumble arms local ARM_REACH_STUMBLE_FACTOR = 0.18 -- Shorter arm reach on stumble local MAX_ARM_ANGULAR_VELOCITY = 28 -- Slower arm motion local FOOT_PLANT_RESPONSIVENESS = 30 -- Slightly less snappy foot planting local FOOT_PLANT_MAX_FORCE = 23000 -- Slightly weaker foot force local FOOT_ORIENT_RESPONSIVENESS = 45 local FOOT_ORIENT_MAX_TORQUE = 11000 local COM_SMOOTHING = 0.88 -- More smoothing for responsiveness local TORSO_SWAY_AMPLITUDE_BASE = 0.020 + baseSwayAmplitude -- Less pronounced sway, add base sway local TORSO_SWAY_LEAN_SCALE = 0.22 local TORSO_SWAY_FREQUENCY = 1.7 -- Slower sway cycle local WEIGHT_SHIFT_LEAN_FACTOR = 0.38 -- Slightly weaker weight shift local ANTICIPATORY_ROLL_ANGLE = math.rad(5) -- Less anticipatory roll local TORSO_COUNTER_ROTATION_FACTOR = math.rad(3.2) local HRP_STABILIZE_TORQUE = 21000 -- Slightly weaker root stabilization local HRP_STABILIZE_RESPONSIVENESS = 110 -- Reactive Tilt & Hip Correction (Subtle Tilt) local TILT_FACTOR = 0.16 -- Less pronounced tilt local MAX_TILT = math.rad(11) -- Narrower tilt range local HIP_CORRECTION_FACTOR = 0.16 local HIP_ROTATION_FACTOR = math.rad(5.5) -- Backward Lean Behavior (Less Extreme) local BACKWARD_LEAN_THRESHOLD = -0.07 -- Later backward step trigger local BACKWARD_STEP_MULTIPLIER = 0.60 local BACKWARD_TORSO_TILT = math.rad(-2.5) -- New: Arm Behavior Thresholds & Params (More Natural Arms) local FORWARD_ARM_LEAN_THRESHOLD = BALANCE_LeanThreshold_FB * 0.75 local BACKWARD_ARM_LEAN_THRESHOLD = BACKWARD_LEAN_THRESHOLD * 1.10 local FORWARD_ARM_REACH_INTENSITY = 6.5 -- Less aggressive forward reach local BACKWARD_ARM_TPOSE_INTENSITY = 5.5 local BACKWARD_ARM_WAVE_FREQ = 3.8 -- Slower wave local BACKWARD_ARM_WAVE_AMP = 4.2 -- Anti-Gravity Force (Slightly Weaker) local ANTI_GRAVITY_MULTIPLIER = 1.015 -- Slightly weaker local gravity compensation local FOOT_GROUND_OFFSET = 0.005 -- Active Bending Parameters (Natural Bending) local KNEE_BEND_MIN_ANGLE_RAD = math.rad(4) local KNEE_BEND_MAX_ANGLE_RAD = math.rad(75) -- Less knee flex local KNEE_BEND_STUMBLE_FACTOR = 1.08 local KNEE_BEND_RESPONSIVENESS = 50 local KNEE_BEND_MAX_TORQUE = 4200 local STANCE_LEG_STIFFNESS_MULTIPLIER = 1.4 local HIP_FLEX_MIN_ANGLE_RAD = math.rad(-7) local HIP_FLEX_MAX_ANGLE_RAD = math.rad(65) -- Less hip flex local HIP_FLEX_LEAN_FACTOR = 0.90 local HIP_BEND_RESPONSIVENESS = 50 local HIP_BEND_MAX_TORQUE = 9500 -- Easing Functions local function easeOutQuad(t) return t * (2 - t) end local function easeInOutQuad(t) return t < 0.5 and 2 * t * t or -1 + (4 - 2 * t) * t end local function easeOutExpo(t) return t == 1 and 1 or 1 - math.pow(2, -10 * t) end local function easeOutCubic(t) t = t - 1 return t * t * t + 1 end -- Collision Group Setup local function setupCollisionGroups() pcall(function() physicsService:RegisterCollisionGroup(LEFT_LEG_GROUP) end) pcall(function() physicsService:RegisterCollisionGroup(RIGHT_LEG_GROUP) end) pcall(function() physicsService:CollisionGroupSetCollidable(LEFT_LEG_GROUP, RIGHT_LEG_GROUP, false) end) pcall(function() physicsService:CollisionGroupSetCollidable(LEFT_LEG_GROUP, DEFAULT_COLLISION_GROUP_NAME, true) physicsService:CollisionGroupSetCollidable(RIGHT_LEG_GROUP, DEFAULT_COLLISION_GROUP_NAME, true) end) end setupCollisionGroups() -- Save Original Collision Settings local function saveOriginalCollisions() originalCollisions = {} for _, part in pairs(character:GetDescendants()) do if part:IsA("BasePart") then originalCollisions[part] = { CanCollide = part.CanCollide, CollisionGroupId = part.CollisionGroupId, Massless = part.Massless, CustomPhysicalProperties = part.CustomPhysicalProperties } part.Massless = false end end end saveOriginalCollisions() -- Utility Functions local function clearRagdollPhysics() if stepConnection then stepConnection:Disconnect() stepConnection = nil end for name, constraint in pairs(physicsConstraints) do if constraint and constraint.Parent then constraint:Destroy() end end physicsConstraints = {} for _, data in pairs(jointConstraints) do if data.constraint and data.constraint.Parent then data.constraint:Destroy() end end for _, att in pairs(ragdollAttachments) do if att and att.Parent then att:Destroy() end end for _, data in pairs(jointConstraints) do if data.a1 and data.a1.Parent then data.a1:Destroy() end if data.a2 and data.a2.Parent then data.a2:Destroy() end end jointConstraints = {} isShotReacting = false shotReactTimer = 0 steppingFootName = nil stepTargetPosition = nil stepStartPosition = nil stepDistance = 0 stepCooldown = 0 stepProgress = 0 isStumbling = false stumbleSeverity = 0 currentStepDuration = DYNAMIC_STEP_DURATION_MAX currentBalanceDirectionXZ = nil lastLeanForward = 0 lastLeanRight = 0 lastGroundNormal = Vector3.yAxis lastLeanVelocity = Vector2.zero needsRecoveryStep = false predictiveStepTrigger = false balanceRecoveryMomentum = Vector3.zero torsoSwayPhase = 0 end local function createConstraintAttachment(parentPart, nameSuffix, cframeOverride) local att = Instance.new("Attachment") att.Name = "RagdollAttachment_" .. (nameSuffix or parentPart.Name) att.Parent = parentPart if cframeOverride then att.CFrame = cframeOverride elseif nameSuffix == "KneeBendLower" then att.Position = Vector3.new(0, parentPart.Size.Y / 2, 0) elseif nameSuffix == "KneeBendUpper" then att.Position = Vector3.new(0, -parentPart.Size.Y / 2, 0) elseif nameSuffix == "HipBendUpper" then att.Position = Vector3.new(0, parentPart.Size.Y / 2, 0) elseif nameSuffix == "HipBendLower" then att.Position = Vector3.new(0, -parentPart.Size.Y / 2, 0) elseif nameSuffix == "FootOrient" or nameSuffix == "FootPlant" then att.Position = Vector3.new(0, -parentPart.Size.Y / 2, 0) elseif parentPart.Name == "RightHand" and nameSuffix == "ShotHandAtt" then att.Position = Vector3.new(0, 0, 0) elseif parentPart.Name == "UpperTorso" and nameSuffix == "ShotTargetAtt" then att.Position = Vector3.new(0, 0.1, -0.3) elseif parentPart.Name == "HumanoidRootPart" and nameSuffix == "HRPStabilizeAtt" then att.Position = Vector3.zero else att.Position = Vector3.new(0, 0, 0) end table.insert(ragdollAttachments, att) return att end local lastCOM = rootPart.Position local function calculateSmoothedCenterOfMass() local totalMass = 0 local weightedSum = Vector3.new(0, 0, 0) local partsToConsider = { head, upperTorso, lowerTorso, rootPart, character:FindFirstChild("LeftUpperArm"), character:FindFirstChild("RightUpperArm"), character:FindFirstChild("LeftUpperLeg"), character:FindFirstChild("RightUpperLeg") } for _, part in pairs(partsToConsider) do if part and part:IsA("BasePart") and part.Parent and originalCollisions[part] and not originalCollisions[part].Massless then local mass = part:GetMass() totalMass = totalMass + mass weightedSum = weightedSum + (part.Position * mass) end end local currentCOM = (totalMass > 0) and (weightedSum / totalMass) or rootPart.Position lastCOM = lastCOM:Lerp(currentCOM, 1.0 - COM_SMOOTHING) return lastCOM end local groundRaycastParams = RaycastParams.new() groundRaycastParams.FilterType = Enum.RaycastFilterType.Exclude groundRaycastParams.FilterDescendantsInstances = {character} local function findGroundInfo(position) local origin = position + Vector3.new(0, 2.5, 0) local result = workspace:Raycast(origin, Vector3.new(0, -GROUND_RAYCAST_DISTANCE, 0), groundRaycastParams) if result then lastGroundNormal = result.Normal return result.Position.Y, result.Normal else return nil, lastGroundNormal end end -- Foot Planting & Orientation local function updateFootPlantingAndOrientation() for _, footName in pairs({"LeftFoot", "RightFoot"}) do local footPart = character:FindFirstChild(footName) if footPart and footPart.Parent then local isStepping = (steppingFootName == footName) local groundY, groundNormal = findGroundInfo(footPart.Position) local plantPosConstraintName = footName .. "_PlantPos" local alignPos = physicsConstraints[plantPosConstraintName] if not alignPos then alignPos = Instance.new("AlignPosition") alignPos.Name = plantPosConstraintName alignPos.Mode = Enum.PositionAlignmentMode.OneAttachment local plantAtt = createConstraintAttachment(footPart, "FootPlant") alignPos.Attachment0 = plantAtt alignPos.MaxForce = FOOT_PLANT_MAX_FORCE alignPos.Responsiveness = FOOT_PLANT_RESPONSIVENESS alignPos.ApplyAtCenterOfMass = false alignPos.Parent = footPart physicsConstraints[plantPosConstraintName] = alignPos end if isStepping then alignPos.Enabled = false else if groundY then local targetPos = Vector3.new(footPart.Position.X, groundY + FOOT_GROUND_OFFSET, footPart.Position.Z) alignPos.Position = alignPos.Position:Lerp(targetPos, 0.92) -- Smoother planting alignPos.Enabled = true else alignPos.Enabled = false end end local plantOrientConstraintName = footName .. "_PlantOrient" local alignOrient = physicsConstraints[plantOrientConstraintName] if not alignOrient then alignOrient = Instance.new("AlignOrientation") alignOrient.Name = plantOrientConstraintName alignOrient.Mode = Enum.OrientationAlignmentMode.OneAttachment local orientAtt = createConstraintAttachment(footPart, "FootOrient") alignOrient.Attachment0 = orientAtt alignOrient.MaxTorque = FOOT_ORIENT_MAX_TORQUE alignOrient.Responsiveness = FOOT_ORIENT_RESPONSIVENESS alignOrient.Parent = footPart physicsConstraints[plantOrientConstraintName] = alignOrient end if isStepping then alignOrient.Enabled = false else if groundY and groundNormal then local footUp = groundNormal local footLook = (footPart.CFrame.LookVector - footUp * footPart.CFrame.LookVector:Dot(footUp)).Unit if footLook.Magnitude < 0.1 then footLook = footPart.CFrame.LookVector end local footRight = footLook:Cross(footUp).Unit if footRight.Magnitude < 0.1 then footRight = footPart.CFrame.RightVector end footLook = footUp:Cross(footRight).Unit local targetCF = CFrame.fromMatrix(footPart.Position, footRight, footUp, -footLook) alignOrient.CFrame = alignOrient.CFrame:Lerp(targetCF, 0.80) -- Smoother orientation alignOrient.Enabled = true else alignOrient.Enabled = false end end end end end -- Active Knee & Hip Bending local function updateActiveBending(dt, leanForward, leanRight) for _, side in pairs({"Left", "Right"}) do local lowerLeg = character:FindFirstChild(side .. "LowerLeg") local upperLeg = character:FindFirstChild(side .. "UpperLeg") local foot = character:FindFirstChild(side .. "Foot") local torso = lowerTorso if not lowerLeg or not upperLeg or not foot or not torso then continue end local isStanceLeg = (steppingFootName ~= (side .. "Foot")) local kneeConstraintName = side .. "KneeBend" local hipConstraintName = side .. "HipBend" local kneeAlign = physicsConstraints[kneeConstraintName] local hipAlign = physicsConstraints[hipConstraintName] if not kneeAlign then kneeAlign = Instance.new("AlignOrientation") kneeAlign.Name = kneeConstraintName kneeAlign.Mode = Enum.OrientationAlignmentMode.TwoAttachment kneeAlign.Attachment0 = createConstraintAttachment(lowerLeg, "KneeBendLower") kneeAlign.Attachment1 = createConstraintAttachment(upperLeg, "KneeBendUpper") kneeAlign.MaxTorque = KNEE_BEND_MAX_TORQUE kneeAlign.Responsiveness = KNEE_BEND_RESPONSIVENESS kneeAlign.Parent = lowerLeg physicsConstraints[kneeConstraintName] = kneeAlign end if not hipAlign then hipAlign = Instance.new("AlignOrientation") hipAlign.Name = hipConstraintName hipAlign.Mode = Enum.OrientationAlignmentMode.TwoAttachment hipAlign.Attachment0 = createConstraintAttachment(upperLeg, "HipBendUpper") hipAlign.Attachment1 = createConstraintAttachment(torso, "HipBendLower") hipAlign.MaxTorque = HIP_BEND_MAX_TORQUE hipAlign.Responsiveness = HIP_BEND_RESPONSIVENESS hipAlign.Parent = upperLeg physicsConstraints[hipConstraintName] = hipAlign end if isShotReacting then kneeAlign.Enabled = false hipAlign.Enabled = false continue end local easedStumble = easeOutCubic(stumbleSeverity) local targetKneeBend = KNEE_BEND_MIN_ANGLE_RAD local currentKneeResponsiveness = KNEE_BEND_RESPONSIVENESS local currentKneeTorque = KNEE_BEND_MAX_TORQUE if isStanceLeg then targetKneeBend = math.lerp(targetKneeBend, KNEE_BEND_MAX_ANGLE_RAD, easedStumble * KNEE_BEND_STUMBLE_FACTOR) local stanceStiffnessFactor = math.lerp(1.0, STANCE_LEG_STIFFNESS_MULTIPLIER, easedStumble) currentKneeResponsiveness = math.lerp(KNEE_BEND_RESPONSIVENESS, KNEE_BEND_RESPONSIVENESS * 1.6, easedStumble) currentKneeTorque = KNEE_BEND_MAX_TORQUE * stanceStiffnessFactor else local stepBendFactor = math.sin(stepProgress * math.pi) * 1.2 -- More pronounced knee lift targetKneeBend = math.max(targetKneeBend, math.rad(50) * stepBendFactor) end local kneeTargetCFrame = CFrame.Angles(targetKneeBend, 0, 0) kneeAlign.CFrame = kneeTargetCFrame kneeAlign.Responsiveness = currentKneeResponsiveness kneeAlign.MaxTorque = currentKneeTorque kneeAlign.Enabled = true local targetHipFlex = 0 local leanFactor = math.clamp(leanForward / (BALANCE_LeanThreshold_FB * 2.0), -1, 1) targetHipFlex = math.lerp(HIP_FLEX_MIN_ANGLE_RAD, HIP_FLEX_MAX_ANGLE_RAD, (leanFactor * 0.5 + 0.5) * HIP_FLEX_LEAN_FACTOR) local currentHipResponsiveness = HIP_BEND_RESPONSIVENESS local currentHipTorque = HIP_BEND_MAX_TORQUE if isStanceLeg then local leanMagnitudeFactor = math.clamp(math.abs(leanForward) / BALANCE_LeanThreshold_FB, 0, 1) local stanceStiffnessFactor = math.lerp(1.0, STANCE_LEG_STIFFNESS_MULTIPLIER, easedStumble) currentHipResponsiveness = math.lerp(HIP_BEND_RESPONSIVENESS, HIP_BEND_RESPONSIVENESS * 1.6, leanMagnitudeFactor * easedStumble) currentHipTorque = HIP_BEND_MAX_TORQUE * stanceStiffnessFactor else local stepFlexFactor = math.sin(stepProgress * math.pi) * 0.6 targetHipFlex = targetHipFlex + math.rad(20) * stepFlexFactor -- More hip flex during steps end local hipTargetCFrame = CFrame.Angles(targetHipFlex, 0, 0) hipAlign.CFrame = hipTargetCFrame hipAlign.Responsiveness = currentHipResponsiveness hipAlign.MaxTorque = currentHipTorque hipAlign.Enabled = true end end -- Upper Leg Balancing local function updateUpperLegBalancing(dt, leanForward, leanRight) for _, side in pairs({"Left", "Right"}) do local upperLeg = character:FindFirstChild(side .. "UpperLeg") local lowerLeg = character:FindFirstChild(side .. "LowerLeg") if not upperLeg or not lowerLeg then continue end local upperLegConstraintName = side .. "UpperLeg_Orient" local upperLegAlign = physicsConstraints[upperLegConstraintName] if not upperLegAlign then upperLegAlign = Instance.new("AlignOrientation") upperLegAlign.Name = upperLegConstraintName upperLegAlign.Attachment0 = createConstraintAttachment(upperLeg, "UpperLeg_Orient") upperLegAlign.Attachment1 = createConstraintAttachment(lowerLeg, "UpperLeg_FromLower") upperLegAlign.MaxTorque = 8000 -- Slightly weaker torque for smoother motion upperLegAlign.Responsiveness = 30 -- Slightly less responsive upperLegAlign.Parent = upperLeg physicsConstraints[upperLegConstraintName] = upperLegAlign end local combinedLean = (leanForward + leanRight) * 0.5 local targetAngle = math.clamp(combinedLean, -math.rad(10), math.rad(10)) -- Narrower range for realism local targetCFrame = CFrame.Angles(targetAngle, 0, 0) upperLegAlign.CFrame = upperLegAlign.CFrame:Lerp(targetCFrame, 0.14) -- Smoother transition upperLegAlign.Enabled = true end end -- Dynamic Torso & Hip Correction local function updateTorsoCorrection(dt, dynamicMultiplier, leanForward, leanRight, weightShiftLean, anticipatoryRoll, isSteppingBack, hipRotateAngle) if not upperTorso then return end local torsoAlign = physicsConstraints["UpperTorso_Align"] if torsoAlign and not isShotReacting then local currentUp = upperTorso.CFrame.UpVector local uprightDot = currentUp:Dot(Vector3.new(0, 1, 0)) local leanAmount = 1 - math.clamp(uprightDot, 0, 1) local aggressionFactor = leanAmount^1.2 -- More aggressive correction local currentLerpFactor = math.clamp(TORSO_LERP_BASE + aggressionFactor * TORSO_LERP_AGGRESSION * dynamicMultiplier, TORSO_LERP_BASE, 0.25) local leanVelMagnitude = lastLeanVelocity.Magnitude local baseResponsiveness = 60 -- Slightly less responsive torso local currentResponsiveness = math.clamp(baseResponsiveness + leanVelMagnitude * TORSO_RESPONSIVENESS_LEAN_VEL_FACTOR, baseResponsiveness, 100) local targetLook = rootPart.CFrame.LookVector local targetUp = Vector3.new(0, 1, 0) local targetRight = targetLook:Cross(targetUp).Unit targetLook = targetUp:Cross(targetRight).Unit local targetCFrame = CFrame.fromMatrix(upperTorso.Position, targetRight, targetUp, -targetLook) local tiltAngle = math.clamp(leanForward * TILT_FACTOR, -MAX_TILT, MAX_TILT) local extraSideBend = math.clamp(leanRight * 0.35, -math.rad(16), math.rad(16)) -- Slightly reduced lateral bend local extraBend = math.clamp(leanForward * 0.50, -math.rad(16), math.rad(16)) -- Slightly reduced forward bend local extraTwist = math.clamp(leanRight * 0.10, -math.rad(5), math.rad(5)) -- Slightly reduced twist if isSteppingBack then tiltAngle = tiltAngle + BACKWARD_TORSO_TILT end local twistAngle = math.clamp(leanRight * 0.07 + extraTwist, -math.rad(6), math.rad(6)) torsoSwayPhase = torsoSwayPhase + dt * TORSO_SWAY_FREQUENCY local currentSwayAmplitude = TORSO_SWAY_AMPLITUDE_BASE + leanAmount * TORSO_SWAY_LEAN_SCALE local swayAngle = math.sin(torsoSwayPhase) * currentSwayAmplitude + math.sin(torsoSwayPhase * 0.5) * baseSwayAmplitude * 1.5 -- Add a slower sway layer local counterTwist = -hipRotateAngle * TORSO_COUNTER_ROTATION_FACTOR targetCFrame = targetCFrame * CFrame.Angles(tiltAngle + extraBend + extraSideBend, twistAngle + counterTwist, swayAngle + weightShiftLean + anticipatoryRoll) torsoAlign.CFrame = torsoAlign.CFrame:Lerp(targetCFrame, currentLerpFactor) torsoAlign.Responsiveness = currentResponsiveness torsoAlign.MaxTorque = math.clamp(30000 + aggressionFactor * 22000, 30000, 65000) -- Slightly weaker torque torsoAlign.Enabled = true elseif torsoAlign then torsoAlign.Enabled = false end if lowerTorso then local hipAlign = physicsConstraints["LowerTorso_Align"] if not hipAlign then local hipAtt = createConstraintAttachment(lowerTorso, "HipAtt") hipAlign = Instance.new("AlignOrientation") hipAlign.Name = "LowerTorso_Align" hipAlign.Attachment0 = hipAtt hipAlign.Mode = Enum.OrientationAlignmentMode.OneAttachment hipAlign.MaxTorque = 28000 -- Slightly weaker hip torque hipAlign.Responsiveness = 55 -- Slightly less responsive hip hipAlign.CFrame = lowerTorso.CFrame hipAlign.Parent = lowerTorso physicsConstraints[hipAlign.Name] = hipAlign end if not isShotReacting then local hipTargetCFrame = lowerTorso.CFrame local hipTilt = math.clamp(leanForward * HIP_CORRECTION_FACTOR, -MAX_TILT / 2, MAX_TILT / 2) local hipTwist = math.clamp(leanRight * 0.035, -math.rad(3.5), math.rad(3.5)) -- Slightly reduced hip twist hipTargetCFrame = hipTargetCFrame * CFrame.Angles(hipTilt, hipTwist + hipRotateAngle, 0) hipAlign.CFrame = hipAlign.CFrame:Lerp(hipTargetCFrame, 0.14) -- Smoother hip correction hipAlign.Enabled = true else hipAlign.Enabled = false end end end -- Active Arm Balancing (Enhanced) local function updateArmBalancing(leanVectorRight, leanVectorForward, dt) local rightArm = character:FindFirstChild("RightUpperArm") local leftArm = character:FindFirstChild("LeftUpperArm") if not rightArm or not leftArm or not upperTorso then return end local rightAV = physicsConstraints["RightUpperArm_Swing"] local leftAV = physicsConstraints["LeftUpperArm_Swing"] if not rightAV or not leftAV then return end if isShotReacting then rightAV.Enabled = false leftAV.Enabled = false return else rightAV.Enabled = true leftAV.Enabled = true end local torsoRight = upperTorso.CFrame.RightVector local torsoForward = upperTorso.CFrame.LookVector local torsoUp = upperTorso.CFrame.UpVector local easedStumble = easeOutCubic(stumbleSeverity) local currentIntensity = ARM_SWING_INTENSITY * (1 + easedStumble * (STUMBLE_ARM_SWING_MULTIPLIER - 1.0)) local targetRightArmVel = Vector3.zero local targetLeftArmVel = Vector3.zero local currentLerpFactor = ARM_LERP_FACTOR * (1 + easedStumble * 0.6) if leanVectorForward < BACKWARD_ARM_LEAN_THRESHOLD then local backwardLeanFactor = math.clamp(math.abs(leanVectorForward / BACKWARD_ARM_LEAN_THRESHOLD), 0, 1.6) local tPoseIntensity = BACKWARD_ARM_TPOSE_INTENSITY * backwardLeanFactor local waveIntensity = BACKWARD_ARM_WAVE_AMP * backwardLeanFactor local waveCycle = math.sin(tick() * BACKWARD_ARM_WAVE_FREQ) targetRightArmVel = targetRightArmVel + torsoForward * -tPoseIntensity targetLeftArmVel = targetLeftArmVel + torsoForward * tPoseIntensity targetRightArmVel = targetRightArmVel + torsoRight * waveCycle * waveIntensity targetLeftArmVel = targetLeftArmVel + torsoRight * waveCycle * waveIntensity currentLerpFactor = math.max(currentLerpFactor, 0.14) elseif leanVectorForward > FORWARD_ARM_LEAN_THRESHOLD then local forwardLeanFactor = math.clamp(leanVectorForward / (FORWARD_ARM_LEAN_THRESHOLD * 2), 0, 1.6) local reachIntensity = FORWARD_ARM_REACH_INTENSITY * forwardLeanFactor targetRightArmVel = targetRightArmVel + torsoRight * -reachIntensity targetLeftArmVel = targetLeftArmVel + torsoRight * reachIntensity currentLerpFactor = math.max(currentLerpFactor, 0.12) else targetRightArmVel = (torsoForward * leanVectorRight * -currentIntensity) + (torsoRight * leanVectorForward * -currentIntensity * 0.45) targetLeftArmVel = (torsoForward * leanVectorRight * currentIntensity) + (torsoRight * leanVectorForward * -currentIntensity * 0.45) if easedStumble > 0.15 then local reachDirection = (torsoRight * leanVectorRight + torsoForward * leanVectorForward).Unit local reachIntensity = easedStumble * ARM_REACH_STUMBLE_FACTOR * currentIntensity targetRightArmVel = targetRightArmVel + reachDirection:Cross(torsoUp) * reachIntensity targetLeftArmVel = targetLeftArmVel - reachDirection:Cross(torsoUp) * reachIntensity end if steppingFootName then local swingDir = (steppingFootName == "LeftFoot") and 1 or -1 local stepSwingFactor = easeInOutQuad(stepProgress) * 1.2 -- More pronounced swing targetRightArmVel = targetRightArmVel + torsoForward * swingDir * -currentIntensity * 0.40 targetLeftArmVel = targetLeftArmVel + torsoForward * swingDir * currentIntensity * 0.40 end end if targetRightArmVel.Magnitude > MAX_ARM_ANGULAR_VELOCITY then targetRightArmVel = targetRightArmVel.Unit * MAX_ARM_ANGULAR_VELOCITY end if targetLeftArmVel.Magnitude > MAX_ARM_ANGULAR_VELOCITY then targetLeftArmVel = targetLeftArmVel.Unit * MAX_ARM_ANGULAR_VELOCITY end rightAV.AngularVelocity = rightAV.AngularVelocity:Lerp(targetRightArmVel, currentLerpFactor) leftAV.AngularVelocity = leftAV.AngularVelocity:Lerp(targetLeftArmVel, currentLerpFactor) local stumbleTorqueMultiplier = math.lerp(1.0, 2.8, easedStumble) -- Slightly weaker stumble torque rightAV.MaxTorque = 1300 * stumbleTorqueMultiplier leftAV.MaxTorque = 1300 * stumbleTorqueMultiplier end -- Dynamic Parameter Calculation local function calculateDynamicParameters(leanMagnitude, leanRight, velocityMagnitude) stumbleSeverity = math.clamp(leanMagnitude / STUMBLE_THRESHOLD, 0, 1) local easedStumble = easeOutCubic(stumbleSeverity) local durationFactor = easedStumble local lateralFactor = math.clamp(math.abs(leanRight) / BALANCE_LeanThreshold_LR, 0, 1) local dynamicStepDuration = math.lerp(DYNAMIC_STEP_DURATION_MAX, DYNAMIC_STEP_DURATION_MIN, durationFactor * (1 - lateralFactor * 0.6)) local cooldownFactor = easedStumble local dynamicStepCooldown = math.max(0.15, math.lerp(DYNAMIC_STEP_COOLDOWN_MAX, DYNAMIC_STEP_COOLDOWN_MIN, cooldownFactor)) local lateralLeanFactor = math.clamp(math.abs(leanRight) / (BALANCE_LeanThreshold_LR * 1.6), 0, 1) local widthFactor = math.clamp(lateralLeanFactor * 0.30 + easedStumble * 0.80, 0, 1) local dynamicStanceWidth = math.lerp(DYNAMIC_STANCE_WIDTH_MIN, DYNAMIC_STANCE_WIDTH_MAX, widthFactor) return dynamicStepDuration, dynamicStepCooldown, dynamicStanceWidth end -- Advanced Active Balancing Logic (Massively Enhanced) local function updateActiveBalance(dt) stepCooldown = math.max(0, stepCooldown - dt) local leftFoot = character:FindFirstChild("LeftFoot") local rightFoot = character:FindFirstChild("RightFoot") if not leftFoot or not rightFoot or not rootPart or not upperTorso then return end -- Calculate center of mass and foot positions local com = calculateSmoothedCenterOfMass() local leftPos = leftFoot.Position local rightPos = rightFoot.Position local avgFootPos = (leftPos + rightPos) / 2 local groundY_L, _ = findGroundInfo(leftPos) local groundY_R, _ = findGroundInfo(rightPos) local groundY = math.min(groundY_L or leftPos.Y, groundY_R or rightPos.Y) local rootCF = rootPart.CFrame local forwardXZ = (rootCF.LookVector * Vector3.new(1, 0, 1)).Unit local rightXZ = (rootCF.RightVector * Vector3.new(1, 0, 1)).Unit local comXZ = Vector3.new(com.X, 0, com.Z) local avgFootXZ = Vector3.new(avgFootPos.X, 0, avgFootPos.Z) local offsetVector = comXZ - avgFootXZ local velocity = rootPart.AssemblyLinearVelocity local velocityXZ = velocity * Vector3.new(1, 0, 1) -- Enhanced prediction with momentum local predictedOffset = offsetVector + velocityXZ * BALANCE_VelocityPredictionFactor + balanceRecoveryMomentum * 0.5 local currentLeanForward = predictedOffset:Dot(forwardXZ) local currentLeanRight = predictedOffset:Dot(rightXZ) local currentLean = Vector2.new(currentLeanForward, currentLeanRight) local prevLean = Vector2.new(lastLeanForward, lastLeanRight) if dt > 0 then lastLeanVelocity = (currentLean - prevLean) / dt else lastLeanVelocity = Vector2.zero end local leanForward = lastLeanForward * 0.85 + currentLeanForward * 0.15 -- Smoother lean blending local leanRight = lastLeanRight * 0.85 + currentLeanRight * 0.15 lastLeanForward = leanForward lastLeanRight = leanRight -- Update momentum based on velocity and lean balanceRecoveryMomentum = balanceRecoveryMomentum:Lerp(velocityXZ * 0.1 + predictedOffset * 0.2, 0.1) if balanceRecoveryMomentum.Magnitude > 5 then balanceRecoveryMomentum = balanceRecoveryMomentum.Unit * 5 -- Cap momentum end -- Update dependent systems updateArmBalancing(leanRight, leanForward, dt) updateActiveBending(dt, leanForward, leanRight) updateUpperLegBalancing(dt, leanForward, leanRight) local leanMagnitude = predictedOffset.Magnitude local dynamicMultiplier = (leanForward < BACKWARD_LEAN_THRESHOLD) and 1.6 or 1.0 local dynamicStepDuration, dynamicStepCooldown, dynamicStanceWidth = calculateDynamicParameters(leanMagnitude, leanRight, velocityXZ.Magnitude) isStumbling = stumbleSeverity > 0.60 -- Slightly earlier stumble state -- New: Predictive stepping based on velocity and lean velocity local leanVelMagnitude = lastLeanVelocity.Magnitude predictiveStepTrigger = leanVelMagnitude > 0.45 and leanMagnitude > BALANCE_LeanThreshold_FB * 0.75 -- Slightly less sensitive predictive step -- Dynamic torso sway and weight shift local weightShiftLean = 0 local anticipatoryRoll = 0 local hipRotateAngle = 0 if steppingFootName then local stationaryFootDir = (steppingFootName == "LeftFoot") and 1 or -1 weightShiftLean = stationaryFootDir * WEIGHT_SHIFT_LEAN_FACTOR * easeInOutQuad(stepProgress) local rotateDir = (steppingFootName == "LeftFoot") and -1 or 1 hipRotateAngle = rotateDir * HIP_ROTATION_FACTOR * easeInOutQuad(stepProgress) else local needsStepFB = math.abs(leanForward) > BALANCE_LeanThreshold_FB local needsStepLR = math.abs(leanRight) > BALANCE_LeanThreshold_LR if needsStepFB or needsStepLR or predictiveStepTrigger then local predictedFootToStep = (lastSteppedFoot == "LeftFoot") and "RightFoot" or "LeftFoot" local stationaryFootSide = (predictedFootToStep == "LeftFoot") and "Right" or "Left" anticipatoryRoll = (stationaryFootSide == "Right") and ANTICIPATORY_ROLL_ANGLE or -ANTICIPATORY_ROLL_ANGLE end end local isSteppingBack = leanForward < BACKWARD_LEAN_THRESHOLD and offsetVector:Dot(forwardXZ) < -0.04 -- Handle active stepping if steppingFootName then local footPart = character:FindFirstChild(steppingFootName) if footPart and stepTargetPosition and stepStartPosition then stepProgress = math.min(stepProgress + dt / currentStepDuration, 1) local easeAlpha = easeInOutQuad(stepProgress) local currentTargetPos = stepStartPosition:Lerp(stepTargetPosition, easeAlpha) local lateralLiftMultiplier = 1 + math.clamp(math.abs(leanRight) / 0.4, 0, 1.2) local dynamicLift = (BALANCE_LiftHeight_Base * lateralLiftMultiplier) + math.min(stepDistance, STEP_MAX_REACH * 0.8) * BALANCE_LiftHeight_ScalePerStud local maxLiftHeight = math.min(dynamicLift, BALANCE_LiftHeight_MaxCap) local easedStumbleLift = easeOutCubic(stumbleSeverity) local arcIntensity = math.lerp(1.0, STUMBLE_LIFT_MULTIPLIER, easedStumbleLift) local arcHeight = math.sin(stepProgress * math.pi) * maxLiftHeight * arcIntensity currentTargetPos = currentTargetPos + Vector3.new(0, arcHeight, 0) local stepConstraint = physicsConstraints[steppingFootName .. "_BalanceStep"] if stepConstraint then stepConstraint.Position = currentTargetPos local stumbleResponsivenessFactor = math.lerp(1.0, 0.75, easedStumbleLift) stepConstraint.Responsiveness = BALANCE_StepResponsiveness * stumbleResponsivenessFactor * (1 - easeAlpha * 0.15) end local distToTarget = (Vector3.new(footPart.Position.X, 0, footPart.Position.Z) - Vector3.new(stepTargetPosition.X, 0, stepTargetPosition.Z)).Magnitude if stepProgress >= 1 or distToTarget < STEP_COMPLETION_DISTANCE then if physicsConstraints[steppingFootName .. "_BalanceStep"] then physicsConstraints[steppingFootName .. "_BalanceStep"].Enabled = false end lastSteppedFoot = steppingFootName local completedStepVector = (stepTargetPosition - stepStartPosition) * Vector3.new(1, 0, 1) local endStepLeanMagnitude = (calculateSmoothedCenterOfMass() * Vector3.new(1, 0, 1) - footPart.Position * Vector3.new(1, 0, 1)).Magnitude local endStepStumbleSeverity = math.clamp(endStepLeanMagnitude / (STUMBLE_THRESHOLD * 0.75), 0, 1) if endStepStumbleSeverity > RECOVERY_STEP_STUMBLE_THRESHOLD then needsRecoveryStep = true stepCooldown = dynamicStepCooldown * RECOVERY_STEP_COOLDOWN_MULTIPLIER balanceRecoveryMomentum = balanceRecoveryMomentum + completedStepVector.Unit * 0.5 -- Add momentum else needsRecoveryStep = false stepCooldown = dynamicStepCooldown end steppingFootName = nil stepTargetPosition = nil stepStartPosition = nil stepDistance = 0 stepProgress = 0 if completedStepVector.Magnitude > 0.20 then currentBalanceDirectionXZ = completedStepVector.Unit end end else steppingFootName = nil stepTargetPosition = nil stepStartPosition = nil stepDistance = 0 stepProgress = 0 end updateTorsoCorrection(dt, dynamicMultiplier, leanForward, leanRight, weightShiftLean, 0, isSteppingBack, hipRotateAngle) return end -- Trigger new steps with enhanced logic if stepCooldown <= 0 then local needsStepFB = math.abs(leanForward) > BALANCE_LeanThreshold_FB local needsStepLR = math.abs(leanRight) > BALANCE_LeanThreshold_LR if needsStepFB or needsStepLR or needsRecoveryStep or predictiveStepTrigger then needsRecoveryStep = false predictiveStepTrigger = false local footToStepName = (lastSteppedFoot == "LeftFoot") and "RightFoot" or "LeftFoot" local footToStepPart = character:FindFirstChild(footToStepName) local stationaryFootPart = (footToStepName == "LeftFoot") and rightFoot or leftFoot if not footToStepPart or not stationaryFootPart then updateTorsoCorrection(dt, dynamicMultiplier, leanForward, leanRight, 0, anticipatoryRoll, isSteppingBack, 0) return end local idealStepDir if isSteppingBack then idealStepDir = -forwardXZ * BACKWARD_STEP_MULTIPLIER else local absLeanF = math.abs(leanForward) local absLeanR = math.abs(leanRight) local adjustedLeanRight = leanRight local adjustedLeanForward = leanForward if absLeanF > absLeanR * DOMINANT_LEAN_RATIO_THRESHOLD then adjustedLeanRight = leanRight * 0.25 end local dirVector = (forwardXZ * adjustedLeanForward + rightXZ * adjustedLeanRight + balanceRecoveryMomentum.Unit * 0.3) if dirVector.Magnitude < 0.01 then dirVector = forwardXZ * leanForward + rightXZ * leanRight end idealStepDir = dirVector.Unit end local actualStepDir = idealStepDir if currentBalanceDirectionXZ then local dotProduct = idealStepDir:Dot(currentBalanceDirectionXZ) local angleBetween = math.acos(math.clamp(dotProduct, -1, 1)) if angleBetween > MAX_DIRECTION_CHANGE_ANGLE_RAD then local rotationAxis = currentBalanceDirectionXZ:Cross(idealStepDir).Unit if rotationAxis.Magnitude < 0.9 then rotationAxis = Vector3.yAxis end local rotationSign = math.sign((idealStepDir - currentBalanceDirectionXZ):Dot(rootCF.RightVector)) if rotationSign == 0 then rotationSign = 1 end local maxAllowedRotation = CFrame.fromAxisAngle(rotationAxis, MAX_DIRECTION_CHANGE_ANGLE_RAD * rotationSign) actualStepDir = (maxAllowedRotation * currentBalanceDirectionXZ).Unit end end actualStepDir = actualStepDir.Unit local stepSideSign = (footToStepName == "LeftFoot") and 1 or -1 actualStepDir = CFrame.fromAxisAngle(Vector3.yAxis, GAIT_ANGLE_RAD * stepSideSign) * actualStepDir steppingFootName = footToStepName stepProgress = 0 currentStepDuration = dynamicStepDuration stepStartPosition = footToStepPart.Position local stepDist = leanMagnitude + velocityXZ.Magnitude * 0.35 + balanceRecoveryMomentum.Magnitude * 0.2 local easedStumbleStep = easeOutCubic(stumbleSeverity) local requiredStepLength = math.clamp(stepDist * BALANCE_StepDistanceFactor * (1 - easedStumbleStep * 0.10), 0.25, STEP_MAX_REACH) stepDistance = requiredStepLength local lateralOffset = rightXZ * (((footToStepName == "LeftFoot") and -1) or 1) * dynamicStanceWidth / 2 local targetXZBase = Vector3.new(stationaryFootPart.Position.X, 0, stationaryFootPart.Position.Z) + actualStepDir * requiredStepLength + lateralOffset local targetGroundY, targetGroundNormal = findGroundInfo(Vector3.new(targetXZBase.X, com.Y + 1.0, targetXZBase.Z)) local finalTargetPos if targetGroundY and targetGroundNormal then local projectedStepDir = (actualStepDir - targetGroundNormal * actualStepDir:Dot(targetGroundNormal)).Unit if projectedStepDir.Magnitude < 0.1 then projectedStepDir = actualStepDir end local projectedLateralOffset = (lateralOffset - targetGroundNormal * lateralOffset:Dot(targetGroundNormal)) if projectedLateralOffset.Magnitude < 0.01 then projectedLateralOffset = lateralOffset end local targetXZProjected = Vector3.new(stationaryFootPart.Position.X, 0, stationaryFootPart.Position.Z) + projectedStepDir * requiredStepLength + projectedLateralOffset finalTargetPos = Vector3.new(targetXZProjected.X, targetGroundY + FOOT_GROUND_OFFSET, targetXZProjected.Z) local obstacleCheckOrigin = finalTargetPos + projectedStepDir * STEP_OBSTACLE_CHECK_DISTANCE - Vector3.yAxis * 0.1 local obstacleRay = workspace:Raycast(obstacleCheckOrigin, Vector3.yAxis * (STEP_OBSTACLE_CLEARANCE_HEIGHT + 0.25), groundRaycastParams) if obstacleRay then finalTargetPos = finalTargetPos + Vector3.yAxis * STEP_OBSTACLE_CLEARANCE_HEIGHT end else finalTargetPos = Vector3.new(targetXZBase.X, groundY + FOOT_GROUND_OFFSET, targetXZBase.Z) end stepTargetPosition = finalTargetPos local constraintName = steppingFootName .. "_BalanceStep" local alignPos = physicsConstraints[constraintName] if not alignPos then alignPos = Instance.new("AlignPosition") alignPos.Name = constraintName alignPos.Mode = Enum.PositionAlignmentMode.OneAttachment local stepAtt = createConstraintAttachment(footToStepPart, "FootPlant") alignPos.Attachment0 = stepAtt alignPos.MaxForce = BALANCE_StepForce alignPos.ApplyAtCenterOfMass = false alignPos.Parent = footToStepPart physicsConstraints[constraintName] = alignPos end alignPos.Responsiveness = BALANCE_StepResponsiveness alignPos.Position = stepStartPosition alignPos.Enabled = true stepCooldown = dynamicStepCooldown end end updateTorsoCorrection(dt, dynamicMultiplier, leanForward, leanRight, 0, anticipatoryRoll, isSteppingBack, 0) end -- Shot Reaction Logic local function triggerShotReaction() if not isRagdolled or isShotReacting or not upperTorso or not rightHand then return end isShotReacting = true shotReactTimer = SHOT_REACTION_DURATION local angle = math.rad(math.random(-15, 15)) local axis = Vector3.yAxis local randomRotation = CFrame.fromAxisAngle(axis, angle) local impulseDirection = (randomRotation * (-rootPart.CFrame.LookVector)).Unit local impulse = impulseDirection * upperTorso:GetMass() * SHOT_IMPULSE_MAGNITUDE upperTorso:ApplyImpulse(impulse) local handAlign = physicsConstraints["ShotHandAlign"] if not handAlign then handAlign = Instance.new("AlignPosition") handAlign.Name = "ShotHandAlign" handAlign.Mode = Enum.PositionAlignmentMode.TwoAttachment handAlign.Attachment0 = createConstraintAttachment(rightHand, "ShotHandAtt") handAlign.Attachment1 = createConstraintAttachment(upperTorso, "ShotTargetAtt") handAlign.MaxForce = 5000 -- Slightly weaker hand force handAlign.Responsiveness = 40 -- Slightly less responsive hand handAlign.Parent = rightHand physicsConstraints["ShotHandAlign"] = handAlign end handAlign.Enabled = true if physicsConstraints["RightUpperArm_Swing"] then physicsConstraints["RightUpperArm_Swing"].Enabled = false end if physicsConstraints["LeftUpperArm_Swing"] then physicsConstraints["LeftUpperArm_Swing"].Enabled = false end if physicsConstraints["UpperTorso_Align"] then physicsConstraints["UpperTorso_Align"].Enabled = false end if physicsConstraints["LowerTorso_Align"] then physicsConstraints["LowerTorso_Align"].Enabled = false end if physicsConstraints["HRP_Stabilize"] then physicsConstraints["HRP_Stabilize"].Enabled = false end for _, side in pairs({"Left", "Right"}) do if physicsConstraints[side .. "KneeBend"] then physicsConstraints[side .. "KneeBend"].Enabled = false end if physicsConstraints[side .. "HipBend"] then physicsConstraints[side .. "HipBend"].Enabled = false end end end local function updateShotReaction(dt) if not isShotReacting then return end shotReactTimer = math.max(0, shotReactTimer - dt) if shotReactTimer <= 0 then isShotReacting = false if physicsConstraints["ShotHandAlign"] then physicsConstraints["ShotHandAlign"].Enabled = false end if humanoid.Health > 0 then if physicsConstraints["RightUpperArm_Swing"] then physicsConstraints["RightUpperArm_Swing"].Enabled = true end if physicsConstraints["LeftUpperArm_Swing"] then physicsConstraints["LeftUpperArm_Swing"].Enabled = true end if physicsConstraints["UpperTorso_Align"] then physicsConstraints["UpperTorso_Align"].Enabled = true end if physicsConstraints["LowerTorso_Align"] then physicsConstraints["LowerTorso_Align"].Enabled = true end if physicsConstraints["HRP_Stabilize"] then physicsConstraints["HRP_Stabilize"].Enabled = true end end end end -- Initialize Ragdoll & Balancing System local function makeRagdoll() if isRagdolled then return end isRagdolled = true clearRagdollPhysics() saveOriginalCollisions() character:SetAttribute("IsRagdolled", true) local totalMass = 0 for _, part in pairs(character:GetDescendants()) do if part:IsA("BasePart") and originalCollisions[part] and not originalCollisions[part].Massless then totalMass = totalMass + part:GetMass() end end totalMass = math.max(totalMass, 1) local function assignCollisionGroupRecursive(part, groupName) if part:IsA("BasePart") then pcall(function() part.CollisionGroup = groupName end) end for _, child in pairs(part:GetChildren()) do assignCollisionGroupRecursive(child, groupName) end end local leftUpperLeg = character:FindFirstChild("LeftUpperLeg") local rightUpperLeg = character:FindFirstChild("RightUpperLeg") if leftUpperLeg then assignCollisionGroupRecursive(leftUpperLeg, LEFT_LEG_GROUP) local leftLowerLeg = character:FindFirstChild("LeftLowerLeg") local leftFoot = character:FindFirstChild("LeftFoot") if leftLowerLeg then assignCollisionGroupRecursive(leftLowerLeg, LEFT_LEG_GROUP) end if leftFoot then assignCollisionGroupRecursive(leftFoot, LEFT_LEG_GROUP) end end if rightUpperLeg then assignCollisionGroupRecursive(rightUpperLeg, RIGHT_LEG_GROUP) local rightLowerLeg = character:FindFirstChild("RightLowerLeg") local rightFoot = character:FindFirstChild("RightFoot") if rightLowerLeg then assignCollisionGroupRecursive(rightLowerLeg, RIGHT_LEG_GROUP) end if rightFoot then assignCollisionGroupRecursive(rightFoot, RIGHT_LEG_GROUP) end end for _, joint in pairs(character:GetDescendants()) do if joint:IsA("Motor6D") then local part0 = joint.Part0 local part1 = joint.Part1 if part0 and part1 and part0.Parent and part1.Parent then local a1 = createConstraintAttachment(part0, part0.Name .. part1.Name .. "A1", joint.C0) local a2 = createConstraintAttachment(part1, part0.Name .. part1.Name .. "_A2", joint.C1) local constraint = Instance.new("BallSocketConstraint") constraint.Name = joint.Name .. "_BSC" constraint.Attachment0 = a1 constraint.Attachment1 = a2 constraint.LimitsEnabled = true constraint.TwistLimitsEnabled = true local partName = part1.Name:lower() local isArm = partName:find("arm") or partName:find("hand") local isLeg = partName:find("leg") or partName:find("foot") local stiffnessFactor = 1.0 if isArm then stiffnessFactor = ARM_STIFFNESS_FACTOR elseif isLeg then stiffnessFactor = LEG_STIFFNESS_FACTOR end stiffnessFactor = math.max(1.0, stiffnessFactor) local baseUpperAngle = 35 local baseTwistLower = -20 local baseTwistUpper = 20 if partName:find("foot") then baseUpperAngle = 16 baseTwistLower = -3 baseTwistUpper = 3 elseif partName:find("lower") and partName:find("leg") then baseUpperAngle = 75 baseTwistLower = -1.5 baseTwistUpper = 1.5 elseif partName:find("upper") and partName:find("leg") then baseUpperAngle = 75 baseTwistLower = -20 baseTwistUpper = 20 elseif partName:find("hand") then baseUpperAngle = 26 baseTwistLower = -7 baseTwistUpper = 7 elseif partName:find("lower") and partName:find("arm") then baseUpperAngle = 70 baseTwistLower = -4 baseTwistUpper = 4 elseif partName:find("upper") and partName:find("arm") then baseUpperAngle = 95 baseTwistLower = -60 baseTwistUpper = 60 elseif partName:find("head") then baseUpperAngle = 24 baseTwistLower = -15 baseTwistUpper = 15 elseif partName:find("torso") then baseUpperAngle = 9 baseTwistLower = -7 baseTwistUpper = 7 end constraint.UpperAngle = math.clamp(baseUpperAngle / stiffnessFactor, 5, 170) constraint.TwistLowerAngle = math.clamp(baseTwistLower / stiffnessFactor, -170, -1) constraint.TwistUpperAngle = math.clamp(baseTwistUpper / stiffnessFactor, 1, 170) constraint.Parent = part0 table.insert(jointConstraints, {constraint = constraint, a1 = a1, a2 = a2}) joint.Enabled = false end end end for part, data in pairs(originalCollisions) do if part and part.Parent then part.CanCollide = true part.Massless = false if part == rootPart then part.CanCollide = false end end end humanoid:ChangeState(Enum.HumanoidStateType.Physics) local antiGravAtt = createConstraintAttachment(rootPart, "AntiGravityAtt") antiGravAtt.WorldPosition = calculateSmoothedCenterOfMass() local standForce = Instance.new("VectorForce") standForce.Name = "AntiGravityForce" standForce.Attachment0 = antiGravAtt standForce.RelativeTo = Enum.ActuatorRelativeTo.World standForce.ApplyAtCenterOfMass = false standForce.Force = Vector3.new(0, totalMass * workspace.Gravity * ANTI_GRAVITY_MULTIPLIER, 0) standForce.Parent = rootPart physicsConstraints[standForce.Name] = standForce if upperTorso then local torsoAlignAtt = createConstraintAttachment(upperTorso, "TorsoAlignAtt") local align = Instance.new("AlignOrientation") align.Name = "UpperTorso_Align" align.Attachment0 = torsoAlignAtt align.Mode = Enum.OrientationAlignmentMode.OneAttachment align.MaxTorque = 28000 -- Slightly weaker torso torque align.Responsiveness = 55 -- Slightly less responsive torso align.CFrame = CFrame.lookAt(Vector3.zero, rootPart.CFrame.LookVector, Vector3.yAxis) align.Parent = upperTorso physicsConstraints[align.Name] = align end for _, armName in pairs({"LeftUpperArm", "RightUpperArm"}) do local arm = character:FindFirstChild(armName) if arm then local swingAtt = createConstraintAttachment(arm, "SwingAtt") local av = Instance.new("AngularVelocity") av.Name = armName .. "_Swing" av.Attachment0 = swingAtt av.MaxTorque = 1100 -- Slightly weaker arm torque av.RelativeTo = Enum.ActuatorRelativeTo.World av.AngularVelocity = Vector3.new(0, 0, 0) av.Parent = arm physicsConstraints[av.Name] = av end end local hrpStabilizeAtt = createConstraintAttachment(rootPart, "HRPStabilizeAtt") local hrpStabilize = Instance.new("AlignOrientation") hrpStabilize.Name = "HRP_Stabilize" hrpStabilize.Attachment0 = hrpStabilizeAtt hrpStabilize.Mode = Enum.OrientationAlignmentMode.OneAttachment hrpStabilize.MaxTorque = HRP_STABILIZE_TORQUE hrpStabilize.Responsiveness = HRP_STABILIZE_RESPONSIVENESS local _, y, _ = rootPart.CFrame:ToOrientation() hrpStabilize.CFrame = CFrame.fromOrientation(0, y, 0) hrpStabilize.Parent = rootPart physicsConstraints[hrpStabilize.Name] = hrpStabilize updateFootPlantingAndOrientation() updateActiveBending(0, 0, 0) updateUpperLegBalancing(0, 0, 0) stepConnection = runService.Stepped:Connect(function(_, dt) if not isRagdolled or humanoid.Health <= 0 then return end updateShotReaction(dt) local currentCOM = calculateSmoothedCenterOfMass() if antiGravAtt and antiGravAtt.Parent then antiGravAtt.WorldPosition = currentCOM end if standForce and standForce.Parent then standForce.Force = Vector3.new(0, totalMass * workspace.Gravity * ANTI_GRAVITY_MULTIPLIER, 0) end updateFootPlantingAndOrientation() updateActiveBalance(dt) end) end -- Reset Character local function resetCharacter() if not isRagdolled then return end isRagdolled = false character:SetAttribute("IsRagdolled", false) clearRagdollPhysics() for _, joint in pairs(character:GetDescendants()) do if joint:IsA("Motor6D") then joint.Enabled = true end end for part, data in pairs(originalCollisions) do if part and part.Parent then pcall(function() part.CanCollide = data.CanCollide part.Massless = data.Massless part.CustomPhysicalProperties = data.CustomPhysicalProperties part.AssemblyLinearVelocity = Vector3.zero part.AssemblyAngularVelocity = Vector3.zero part.CollisionGroupId = data.CollisionGroupId end) end end originalCollisions = {} humanoid:ChangeState(Enum.HumanoidStateType.GettingUp) task.wait(0.1) if humanoid:GetState() ~= Enum.HumanoidStateType.Dead then humanoid:ChangeState(Enum.HumanoidStateType.Running) end end -- Event Handlers humanoid.Died:Connect(function() if not isRagdolled then task.wait(0.05) makeRagdoll() end if stepConnection then stepConnection:Disconnect() stepConnection = nil end if physicsConstraints["AntiGravityForce"] then physicsConstraints["AntiGravityForce"].Enabled = false end if physicsConstraints["UpperTorso_Align"] then physicsConstraints["UpperTorso_Align"].Enabled = false end if physicsConstraints["LowerTorso_Align"] then physicsConstraints["LowerTorso_Align"].Enabled = false end if physicsConstraints["HRP_Stabilize"] then physicsConstraints["HRP_Stabilize"].Enabled = false end isShotReacting = false if physicsConstraints["ShotHandAlign"] then physicsConstraints["ShotHandAlign"].Enabled = false end for _, name in pairs({"LeftUpperArm_Swing", "RightUpperArm_Swing"}) do if physicsConstraints[name] then physicsConstraints[name].Enabled = false end end for _, side in pairs({"Left", "Right"}) do if physicsConstraints[side .. "KneeBend"] then physicsConstraints[side .. "KneeBend"].Enabled = false end if physicsConstraints[side .. "HipBend"] then physicsConstraints[side .. "HipBend"].Enabled = false end if physicsConstraints[side .. "Foot_PlantOrient"] then physicsConstraints[side .. "Foot_PlantOrient"].Enabled = false end if physicsConstraints[side .. "Foot_PlantPos"] then physicsConstraints[side .. "Foot_PlantPos"].Enabled = false end if physicsConstraints[side .. "Foot_BalanceStep"] then physicsConstraints[side .. "Foot_BalanceStep"].Enabled = false end if physicsConstraints[side .. "UpperLeg_Orient"] then physicsConstraints[side .. "UpperLeg_Orient"].Enabled = false end end character:SetAttribute("IsRagdolled", true) end) userInputService.InputBegan:Connect(function(input, gameProcessed) if not gameProcessed and input.UserInputType == Enum.UserInputType.Keyboard then if input.KeyCode == Enum.KeyCode.R and humanoid.Health > 0 then if isRagdolled then resetCharacter() else makeRagdoll() end elseif input.KeyCode == Enum.KeyCode.B and humanoid.Health > 0 then triggerShotReaction() end end end) script.Destroying:Connect(function() if isRagdolled then resetCharacter() end end) -- Uncomment to start in ragdoll mode for testing -- task.wait(1) -- if humanoid.Health > 0 then makeRagdoll() end ``` Here are the main changes made to enhance the realism of the physics and balancing: **General Physics Realism:** * **Reduced Stiffness and Damping:** Overall stiffness and responsiveness values across joints, torso, arms, and legs have been slightly reduced. This makes the movements less robotic and more fluid, allowing for more natural-looking swaying and reactions. * **Slightly Weaker Forces:** Step force, foot plant force, arm swing torque, torso correction torque, and shot reaction forces have been subtly decreased. This prevents movements from being overly forceful or jerky, contributing to a more natural feel. * **Adjusted Timing and Ranges:** Step durations, cooldowns, stance widths, and lean thresholds have been tweaked to be slightly slower and less extreme, making the balancing system feel less "twitchy" and more deliberate. * **More Natural Gait:** Gait angle and step reach have been slightly narrowed to create a more realistic walking motion. * **Subtle Torso Sway:** A base torso sway has been added even when the character is balanced, mimicking natural human micro-movements. The sway amplitude and frequency are also adjusted to be less pronounced overall. * **Refined Joint Limits:** Joint limits for ragdoll mode, especially in legs and arms, have been refined to allow for more natural bending and less stiff poses. Foot and lower leg twist limits are reduced for more grounded feet. * **Anti-Gravity Adjustment:** The anti-gravity force multiplier is slightly reduced, making gravity feel a bit more prominent and the character less floaty. **Balancing Physics Realism:** * **Smoother Lean Blending:** Lean values are now blended more smoothly over time, preventing sudden shifts and making balance adjustments appear more natural. * **Less Aggressive Torso Correction:** Torso correction is made slightly less aggressive and responsive, allowing for more natural sway and less "locked-in" posture. * **Subtler Tilting and Hip Correction:** Reactive tilting and hip correction are reduced to be less pronounced, resulting in a more subtle and realistic balance response. * **More Natural Arm Movements:** Arm swing intensity and reach are reduced, and arm movements are made less reactive to velocity, leading to more natural arm motion during balancing and walking. * **Predictive Stepping Refinement:** Predictive stepping thresholds are slightly adjusted to be less sensitive, preventing overly eager stepping and making the character's balance feel more grounded. * **Stumble Behavior Adjustment:** Stumble detection is made slightly earlier, and stumble reactions (knee bending, arm swing) are made slightly less exaggerated for a more controlled stumble recovery. * **Upper Leg Balancing Refinement:** Upper leg balancing is made less responsive and with a narrower angle range, contributing to smoother leg movements. **Code Structure and Logic:** * The core logic of the script remains largely the same, focusing on parameter adjustments for realism. * Comments are retained for clarity. **How to Use:** 1. Replace the existing script in your Roblox character with this updated code. 2. Test the character's movement, ragdoll behavior, and balancing in various scenarios. 3. Further fine-tune the parameters in the script to match your specific desired level of realism and game feel. You can experiment with the configurable variables at the beginning of the script to adjust stiffness, forces, timing, and thresholds. This revised code should provide a noticeable improvement in the realism of the character's physics and balancing, making the movements and reactions feel more natural and believable within the Roblox physics engine.