void UpdateWalkAnim(float deltaTime) { if (CurrentGroundedParams == null) { return; } movement = MathUtils.SmoothStep(movement, TargetMovement, 0.2f); Collider.LinearVelocity = new Vector2( movement.X, Collider.LinearVelocity.Y > 0.0f ? Collider.LinearVelocity.Y * 0.5f : Collider.LinearVelocity.Y); //limbs are disabled when simple physics is enabled, no need to move them if (SimplePhysicsEnabled) { return; } float mainLimbHeight = ColliderHeightFromFloor; Vector2 colliderBottom = GetColliderBottom(); float movementAngle = 0.0f; float mainLimbAngle = (MainLimb.type == LimbType.Torso ? TorsoAngle ?? 0 : HeadAngle ?? 0) * Dir; while (MainLimb.Rotation - (movementAngle + mainLimbAngle) > MathHelper.Pi) { movementAngle += MathHelper.TwoPi; } while (MainLimb.Rotation - (movementAngle + mainLimbAngle) < -MathHelper.Pi) { movementAngle -= MathHelper.TwoPi; } Limb torso = GetLimb(LimbType.Torso); if (torso != null) { if (TorsoAngle.HasValue) { SmoothRotateWithoutWrapping(torso, movementAngle + TorsoAngle.Value * Dir, MainLimb, TorsoTorque); } if (TorsoPosition.HasValue) { Vector2 pos = colliderBottom + Vector2.UnitY * TorsoPosition.Value; if (torso != MainLimb) { pos.X = torso.SimPosition.X; } else { mainLimbHeight = TorsoPosition.Value; } torso.MoveToPos(pos, TorsoMoveForce); torso.PullJointEnabled = true; torso.PullJointWorldAnchorB = pos; } } Limb head = GetLimb(LimbType.Head); if (head != null) { if (HeadAngle.HasValue) { SmoothRotateWithoutWrapping(head, movementAngle + HeadAngle.Value * Dir, MainLimb, HeadTorque); } if (HeadPosition.HasValue) { Vector2 pos = colliderBottom + Vector2.UnitY * HeadPosition.Value; if (head != MainLimb) { pos.X = head.SimPosition.X; } else { mainLimbHeight = HeadPosition.Value; } head.MoveToPos(pos, HeadMoveForce); head.PullJointEnabled = true; head.PullJointWorldAnchorB = pos; } } if (TailAngle.HasValue) { var tail = GetLimb(LimbType.Tail); if (tail != null) { SmoothRotateWithoutWrapping(tail, movementAngle + TailAngle.Value * Dir, MainLimb, TailTorque); } } WalkPos -= MainLimb.LinearVelocity.X * (CurrentAnimationParams.CycleSpeed / RagdollParams.JointScale / 100.0f); Vector2 transformedStepSize = Vector2.Zero; if (Math.Abs(TargetMovement.X) > 0.01f) { transformedStepSize = new Vector2( (float)Math.Cos(WalkPos) * StepSize.Value.X * 3.0f, (float)Math.Sin(WalkPos) * StepSize.Value.Y * 2.0f); } foreach (Limb limb in Limbs) { switch (limb.type) { case LimbType.LeftFoot: case LimbType.RightFoot: Vector2 footPos = new Vector2(limb.SimPosition.X, colliderBottom.Y); if (limb.RefJointIndex > -1) { if (LimbJoints.Length <= limb.RefJointIndex) { DebugConsole.ThrowError($"Reference joint index {limb.RefJointIndex} is out of array. This is probably due to a missing joint. If you just deleted a joint, don't do that without first removing the reference joint indices from the limbs. If this is not the case, please ensure that you have defined the index to the right joint."); } else { footPos.X = LimbJoints[limb.RefJointIndex].WorldAnchorA.X; } } footPos.X += limb.StepOffset.X * Dir; footPos.Y += limb.StepOffset.Y; if (limb.type == LimbType.LeftFoot) { limb.DebugRefPos = footPos + Vector2.UnitX * movement.X * 0.1f; limb.DebugTargetPos = footPos + new Vector2( transformedStepSize.X + movement.X * 0.1f, (transformedStepSize.Y > 0.0f) ? transformedStepSize.Y : 0.0f); limb.MoveToPos(limb.DebugTargetPos, FootMoveForce); } else if (limb.type == LimbType.RightFoot) { limb.DebugRefPos = footPos + Vector2.UnitX * movement.X * 0.1f; limb.DebugTargetPos = footPos + new Vector2( -transformedStepSize.X + movement.X * 0.1f, (-transformedStepSize.Y > 0.0f) ? -transformedStepSize.Y : 0.0f); limb.MoveToPos(limb.DebugTargetPos, FootMoveForce); } if (CurrentGroundedParams.FootAnglesInRadians.ContainsKey(limb.limbParams.ID)) { SmoothRotateWithoutWrapping(limb, movementAngle + CurrentGroundedParams.FootAnglesInRadians[limb.limbParams.ID] * Dir, MainLimb, FootTorque); } break; case LimbType.LeftLeg: case LimbType.RightLeg: if (Math.Abs(CurrentGroundedParams.LegTorque) > 0.001f) { limb.body.ApplyTorque(limb.Mass * CurrentGroundedParams.LegTorque * Dir); } break; } } }
void UpdateWalkAnim(float deltaTime) { movement = MathUtils.SmoothStep(movement, TargetMovement, 0.2f); Collider.LinearVelocity = new Vector2( movement.X, Collider.LinearVelocity.Y > 0.0f ? Collider.LinearVelocity.Y * 0.5f : Collider.LinearVelocity.Y); //limbs are disabled when simple physics is enabled, no need to move them if (SimplePhysicsEnabled) { return; } Vector2 colliderBottom = GetColliderBottom(); float movementAngle = 0.0f; var mainLimb = MainLimb; float mainLimbAngle = (mainLimb.type == LimbType.Torso ? TorsoAngle ?? 0 : HeadAngle ?? 0) * Dir; while (mainLimb.Rotation - (movementAngle + mainLimbAngle) > MathHelper.Pi) { movementAngle += MathHelper.TwoPi; } while (mainLimb.Rotation - (movementAngle + mainLimbAngle) < -MathHelper.Pi) { movementAngle -= MathHelper.TwoPi; } float stepLift = TargetMovement.X == 0.0f ? 0 : (float)Math.Sin(WalkPos * CurrentGroundedParams.StepLiftFrequency + MathHelper.Pi * CurrentGroundedParams.StepLiftOffset) * (CurrentGroundedParams.StepLiftAmount / 100); float limpAmount = character.GetLegPenalty(); if (limpAmount > 0) { float walkPosX = (float)Math.Cos(WalkPos); //make the footpos oscillate when limping limpAmount = Math.Max(Math.Abs(walkPosX) * limpAmount, 0.0f) * Math.Min(Math.Abs(TargetMovement.X), 0.3f) * Dir; } Limb torso = GetLimb(LimbType.Torso); if (torso != null) { if (TorsoAngle.HasValue) { SmoothRotateWithoutWrapping(torso, movementAngle + TorsoAngle.Value * Dir, mainLimb, TorsoTorque); } if (TorsoPosition.HasValue) { Vector2 pos = colliderBottom + new Vector2(limpAmount, TorsoPosition.Value + stepLift); if (torso != mainLimb) { pos.X = torso.SimPosition.X; } torso.MoveToPos(pos, TorsoMoveForce); torso.PullJointEnabled = true; torso.PullJointWorldAnchorB = pos; } } Limb head = GetLimb(LimbType.Head); if (head != null) { if (HeadAngle.HasValue) { SmoothRotateWithoutWrapping(head, movementAngle + HeadAngle.Value * Dir, mainLimb, HeadTorque); } if (HeadPosition.HasValue) { Vector2 pos = colliderBottom + new Vector2(limpAmount, HeadPosition.Value + stepLift * CurrentGroundedParams.StepLiftHeadMultiplier); if (head != mainLimb) { pos.X = head.SimPosition.X; } head.MoveToPos(pos, HeadMoveForce); head.PullJointEnabled = true; head.PullJointWorldAnchorB = pos; } } if (TailAngle.HasValue) { var tail = GetLimb(LimbType.Tail); if (tail != null) { SmoothRotateWithoutWrapping(tail, movementAngle + TailAngle.Value * Dir, mainLimb, TailTorque); } } float prevWalkPos = WalkPos; WalkPos -= mainLimb.LinearVelocity.X * (CurrentAnimationParams.CycleSpeed / RagdollParams.JointScale / 100.0f); Vector2 transformedStepSize = Vector2.Zero; if (Math.Abs(TargetMovement.X) > 0.01f) { transformedStepSize = new Vector2( (float)Math.Cos(WalkPos) * StepSize.Value.X * 3.0f, (float)Math.Sin(WalkPos) * StepSize.Value.Y * 2.0f); } foreach (Limb limb in Limbs) { if (limb.IsSevered) { continue; } if (Math.Abs(limb.Params.ConstantTorque) > 0) { limb.body.SmoothRotate(movementAngle + MathHelper.ToRadians(limb.Params.ConstantAngle) * Dir, limb.Params.ConstantTorque, wrapAngle: true); } switch (limb.type) { case LimbType.LeftFoot: case LimbType.RightFoot: Vector2 footPos = new Vector2(limb.SimPosition.X, colliderBottom.Y); if (limb.RefJointIndex > -1) { if (LimbJoints.Length <= limb.RefJointIndex) { DebugConsole.ThrowError($"Reference joint index {limb.RefJointIndex} is out of array. This is probably due to a missing joint. If you just deleted a joint, don't do that without first removing the reference joint indices from the limbs. If this is not the case, please ensure that you have defined the index to the right joint."); } else { footPos.X = LimbJoints[limb.RefJointIndex].WorldAnchorA.X; } } footPos.X += limb.StepOffset.X * Dir; footPos.Y += limb.StepOffset.Y; bool playFootstepSound = false; if (limb.type == LimbType.LeftFoot) { if (Math.Sign(Math.Sin(prevWalkPos)) > 0 && Math.Sign(transformedStepSize.Y) < 0) { playFootstepSound = true; } limb.DebugRefPos = footPos + Vector2.UnitX * movement.X * 0.1f; limb.DebugTargetPos = footPos + new Vector2( transformedStepSize.X + movement.X * 0.1f, (transformedStepSize.Y > 0.0f) ? transformedStepSize.Y : 0.0f); limb.MoveToPos(limb.DebugTargetPos, FootMoveForce); } else if (limb.type == LimbType.RightFoot) { if (Math.Sign(Math.Sin(prevWalkPos)) < 0 && Math.Sign(transformedStepSize.Y) > 0) { playFootstepSound = true; } limb.DebugRefPos = footPos + Vector2.UnitX * movement.X * 0.1f; limb.DebugTargetPos = footPos + new Vector2( -transformedStepSize.X + movement.X * 0.1f, (-transformedStepSize.Y > 0.0f) ? -transformedStepSize.Y : 0.0f); limb.MoveToPos(limb.DebugTargetPos, FootMoveForce); } if (playFootstepSound) { #if CLIENT PlayImpactSound(limb); #endif } if (CurrentGroundedParams.FootAnglesInRadians.ContainsKey(limb.Params.ID)) { SmoothRotateWithoutWrapping(limb, movementAngle + CurrentGroundedParams.FootAnglesInRadians[limb.Params.ID] * Dir, mainLimb, FootTorque); } break; case LimbType.LeftLeg: case LimbType.RightLeg: if (Math.Abs(CurrentGroundedParams.LegTorque) > 0) { limb.body.ApplyTorque(limb.Mass * CurrentGroundedParams.LegTorque * Dir); } break; } } }