Ejemplo n.º 1
0
        void FixedUpdate()
        {
            // Check if on a solid surface
            grounded = (collisionFlags & CollisionFlags.Below) != 0;

            // Clear movement
            if (cancelMovement)
            {
                moveDirection  = Vector3.zero;
                cancelMovement = false;
                groundMotor.ClearActivePlatform();
                acrobatMotor.ClearFallingDamage();
                return;
            }

            // Handle freeze movement
            if (freezeMotor > 0)
            {
                freezeMotor -= Time.deltaTime;
                if (freezeMotor <= 0)
                {
                    freezeMotor    = 0;
                    CancelMovement = true;
                }
                return;
            }

            playerScanner.FindHeadHit(new Ray(controller.transform.position, Vector3.up));
            playerScanner.SetHitSomethingInFront();
            // Check if should hang
            hangingMotor.HangingChecks();
            // Handle Rappeling
            rappelMotor.RappelChecks();
            // Handle climbing
            climbingMotor.ClimbingCheck();

            // Do nothing if player levitating/swimming or climbing - replacement motor will take over movement for levitating/swimming
            if (levitateMotor && (levitateMotor.IsLevitating || levitateMotor.IsSwimming) || climbingMotor.IsClimbing || hangingMotor.IsHanging)
            {
                moveDirection = Vector3.zero;
                return;
            }


            if (climbingMotor.WallEject)
            {   // True in terms of the player having their feet on solid surface.
                grounded = true;
            }

            if (grounded)
            {
                acrobatMotor.Jumping = false;

                acrobatMotor.CheckFallingDamage();

                // checks if sliding and applies movement to moveDirection if true
                frictionMotor.GroundedMovement(ref moveDirection);

                acrobatMotor.HandleJumpInput(ref moveDirection);
            }
            else
            {
                acrobatMotor.CheckInitFall(ref moveDirection);

                acrobatMotor.CheckAirControl(ref moveDirection, speed);
            }

            playerScanner.FindStep(moveDirection);

            acrobatMotor.ApplyGravity(ref moveDirection);

            acrobatMotor.HitHead(ref moveDirection);

            groundMotor.MoveWithMovingPlatform(moveDirection);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Perform Climbing Movement
        /// </summary>
        private void ClimbMovement()
        {
            // Try to move along wall and forwards at same time
            // This helps player maintain collision checks with the wall and step onto the ledge once it's found

            // if strafing to either side, this will be set so we can check for wrap-around corners.
            Vector3 checkDirection = Vector3.zero;

            if (!isSlipping)
            {
                float climbScalar = speedChanger.GetClimbingSpeed(playerMotor.Speed);
                moveDirection = Vector3.zero;
                bool movedForward  = InputManager.Instance.HasAction(InputManager.Actions.MoveForwards);
                bool movedBackward = InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards);
                bool movedLeft     = InputManager.Instance.HasAction(InputManager.Actions.MoveLeft);
                bool movedRight    = InputManager.Instance.HasAction(InputManager.Actions.MoveRight);

                if (DaggerfallUnity.Settings.AdvancedClimbing)
                {
                    bool hitSomethingInFront = moveScanner.HitSomethingInFront;
                    #region Vertical Climbing
                    // TODO: Disallow rappel when pressing back if auto climbing
                    if (!movedBackward && !atOutsideCorner && (movedForward || !hitSomethingInFront))
                    {
                        // TODO: devise horizontal distance-based solution to terminate forward movement
                        // It may fix the problem of climbing to the top of gabled roofs.
                        if (!overrideSkillCheck)
                        {
                            overrideSkillCheck = !hitSomethingInFront;
                        }
                        moveDirection.y = Vector3.up.y * climbScalar;
                    }
                    else if (movedBackward)
                    {
                        moveDirection.y = Vector3.down.y * climbScalar;
                    }
                    #endregion
                    #region Horizontal Climbing
                    if (movedRight || movedLeft)
                    {
                        float checkScalar = controller.radius + 0.5f;
                        if (movedRight)
                        {
                            checkDirection = Vector3.Cross(Vector3.up, myLedgeDirection).normalized;
                        }
                        else if (movedLeft)
                        {
                            checkDirection = Vector3.Cross(myLedgeDirection, Vector3.up).normalized;
                        }

                        // adjust direction so it can intersect with adjacentWallRay
                        myStrafeRay.direction = checkDirection;
                        Debug.DrawRay(myStrafeRay.origin, myStrafeRay.direction, Color.red);

                        // perform check for adjacent wall
                        GetAdjacentWallInfo(controller.transform.position, checkDirection * checkScalar, movedLeft ? PlayerMoveScanner.RotationDirection.XZClockwise : PlayerMoveScanner.RotationDirection.XZCounterClockwise);

                        Vector3 intersection;
                        Vector3 intersectionOrthogonal;
                        Vector3 wrapDirection = Vector3.zero; // direction to move while wrapping around corner
                        // did we find the wall corner intersection?
                        if (LineLineIntersection(out intersection, myStrafeRay.origin, myStrafeRay.direction, adjacentWallRay.origin, adjacentWallRay.direction))
                        {
                            intersectionOrthogonal = (-myLedgeDirection - adjacentLedgeDirection).normalized;
                            Debug.DrawRay(intersection, intersectionOrthogonal, Color.yellow);
                            atOutsideCorner = ((myStrafeRay.origin - intersection).magnitude < 0.01f);
                            if (atOutsideCorner)
                            {
                                // perform outside corner wrap
                                if (movedRight)
                                {
                                    wrapDirection = Vector3.Cross(intersectionOrthogonal, Vector3.up).normalized;
                                }
                                else if (movedLeft)
                                {
                                    wrapDirection = Vector3.Cross(Vector3.up, intersectionOrthogonal).normalized;
                                }
                            }

                            cornerNormalRay = new Ray(intersection, intersectionOrthogonal);
                        }

                        // exiting outside wall corner?
                        if (atInsideCorner || (atOutsideCorner && IsAlmostParallel(wrapDirection, adjacentWallRay.direction)))
                        {
                            myLedgeDirection = adjacentLedgeDirection;
                            wrapDirection    = -adjacentWallRay.direction;
                            checkDirection   = wrapDirection;
                            atOutsideCorner  = false;
                            atInsideCorner   = false;
                        }

                        // if at outside corner, use corner-updated directions to wrap around it
                        if (atOutsideCorner)
                        {
                            Debug.DrawRay(intersection, wrapDirection, Color.magenta);
                            moveDirection += wrapDirection * climbScalar;
                        }
                        else // move in wasd direction
                        {
                            moveDirection += checkDirection * climbScalar;
                        }
                    }
                    #endregion
                    // need to add horizontal movement towards wall for collision
                    moveDirection.x += wallDirection.x * playerMotor.Speed;
                    moveDirection.z += wallDirection.z * playerMotor.Speed;
                }
                else // do normal climbing
                {
                    moveDirection   = wallDirection * playerMotor.Speed;
                    moveDirection.y = Vector3.up.y * climbScalar;
                }
            }
            else // do slipping down wall
            {
                acrobatMotor.CheckInitFall(ref moveDirection);
                acrobatMotor.ApplyGravity(ref moveDirection);
            }
            // finalize climbing movement
            controller.Move(moveDirection * Time.deltaTime);
            playerMotor.CollisionFlags = controller.collisionFlags;
        }
Ejemplo n.º 3
0
        void FixedUpdate()
        {
            // Clear movement
            if (cancelMovement)
            {
                moveDirection  = Vector3.zero;
                cancelMovement = false;
                groundMotor.ClearActivePlatform();
                acrobatMotor.ClearFallingDamage();
                return;
            }

            // Handle freeze movement
            if (freezeMotor > 0)
            {
                freezeMotor -= Time.deltaTime;
                if (freezeMotor <= 0)
                {
                    freezeMotor    = 0;
                    CancelMovement = true;
                }
                return;
            }

            // Handle climbing
            climbingMotor.ClimbingCheck(ref collisionFlags);

            if (climbingMotor.IsClimbing)
            {
                acrobatMotor.Falling = false;
            }

            // Do nothing if player levitating/swimming or climbing - replacement motor will take over movement for levitating/swimming
            if (levitateMotor && (levitateMotor.IsLevitating || levitateMotor.IsSwimming) || climbingMotor.IsClimbing)
            {
                return;
            }

            // Player assumed to be in movement for now
            standingStill = false;

            if (grounded)
            {
                // Set standing still while grounded flag
                // Casting moveDirection to a Vector2 so constant downward force of gravity not included in magnitude
                standingStill = (new Vector2(moveDirection.x, moveDirection.z).magnitude == 0);

                acrobatMotor.Jumping = false;

                acrobatMotor.CheckFallingDamage();

                // checks if sliding and applies movement to moveDirection if true
                frictionMotor.MoveIfSliding(ref moveDirection);

                acrobatMotor.HandleJumpInput(ref moveDirection);
            }
            else
            {
                acrobatMotor.CheckInitFall();

                acrobatMotor.CheckAirControl(ref moveDirection, speed);
            }

            acrobatMotor.ApplyGravity(ref moveDirection);

            // If we hit something above us AND we are moving up, reverse vertical movement
            if ((controller.collisionFlags & CollisionFlags.Above) != 0)
            {
                if (moveDirection.y > 0)
                {
                    moveDirection.y = -moveDirection.y;
                }
            }

            groundMotor.MoveOnGround(moveDirection, ref collisionFlags, ref grounded);
        }
        /// <summary>
        /// Perform Climbing Movement and call Skill Checks
        /// </summary>
        private void ClimbMovement()
        {
            // Try to move up and forwards at same time
            // This helps player smoothly mantle the top of whatever they are climbing
            // Horizontal distance check in ClimbingCheck() will cancel climb once player mantles
            // This has the happy side effect of fixing issue where player climbs endlessly into sky or starting to climb when not facing wall

            // Climbing effect states "target can climb twice as well" - doubling climbing speed
            float climbingBoost = player.IsEnhancedClimbing ? 2f : 1f;

            if (!isSlipping)
            {
                float climbScalar = (playerMotor.Speed / 3) * climbingBoost;
                moveDirection = ledgeDirection * playerMotor.Speed;

                if (DaggerfallUnity.Settings.AdvancedClimbing)
                {
                    if (InputManager.Instance.HasAction(InputManager.Actions.MoveForwards))
                    {
                        moveDirection.y = Vector3.up.y * climbScalar;
                    }
                    else if (InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards))
                    {
                        moveDirection.y = Vector3.down.y * climbScalar;
                    }

                    if (InputManager.Instance.HasAction(InputManager.Actions.MoveRight))
                    {
                        moveDirection += Vector3.Cross(Vector3.up, ledgeDirection).normalized *climbScalar;
                    }
                    else if (InputManager.Instance.HasAction(InputManager.Actions.MoveLeft))
                    {
                        moveDirection += Vector3.Cross(ledgeDirection, Vector3.up).normalized *climbScalar;
                    }
                }
                else
                {
                    moveDirection.y = Vector3.up.y * climbScalar;
                }
            }
            else
            {
                acrobatMotor.CheckInitFall();
                acrobatMotor.ApplyGravity(ref moveDirection);
            }

            // HACK: Overwrite moveDirection to prevent error where player is shot into air and transformed to tile origin
            // @MeteoricDragon - This cancels advanced climbing and slipping for now, but I just wanted bug removed from next round of builds
            // This clears bug without directly changing your logic above, then you can then fix properly when possible :)
            // This code block can just be removed later once problem is resolved
            if (InputManager.Instance.HasAction(InputManager.Actions.MoveForwards))
            {
                // Climb upwards
                float climbScalar = (playerMotor.Speed / 3) * climbingBoost;
                moveDirection.y = Vector3.up.y * climbScalar;
            }
            else
            {
                // Stop climbing
                isSlipping = false;
                isClimbing = false;
                return;
            }

            controller.Move(moveDirection * Time.deltaTime);
            playerMotor.CollisionFlags = controller.collisionFlags;
        }