예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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;
                }
            }
        }