예제 #1
0
        public override void KeyMovement(Vector3 moveDirection, MovementState movementState)
        {
            if (!CacheEntity.CanMove())
            {
                return;
            }

            switch (CacheEntity.MovementSecure)
            {
            case MovementSecure.ServerAuthoritative:
                // Multiply with 100 and cast to sbyte to reduce packet size
                // then it will be devided with 100 later on server side
                CallNetFunction(NetFuncKeyMovement, DeliveryMethod.Sequenced, FunctionReceivers.Server, new DirectionVector3(moveDirection), movementState);
                break;

            case MovementSecure.NotSecure:
                tempInputDirection = moveDirection;
                tempMovementState  = movementState;
                if (tempInputDirection.sqrMagnitude > 0)
                {
                    navPaths = null;
                }
                if (canFly && !CacheOpenCharacterController.isGrounded && !isUnderWater && tempMovementState.HasFlag(MovementState.IsJump))
                {
                    isFlying          = true;
                    isJumping         = false;
                    applyingJumpForce = false;
                }
                if (!isJumping && !applyingJumpForce)
                {
                    isJumping = (isUnderWater || CacheOpenCharacterController.isGrounded) && tempMovementState.HasFlag(MovementState.IsJump);
                }
                break;
            }
        }
예제 #2
0
 protected void NetFuncPointClickMovement(Vector3 position)
 {
     if (!CacheEntity.CanMove())
     {
         return;
     }
     tempMovementState = MovementState.Forward;
     SetMovePaths(position, true);
 }
예제 #3
0
 protected void NetFuncUpdateYRotation(short yRotation)
 {
     if (!CacheEntity.CanMove())
     {
         return;
     }
     if (!HasNavPaths)
     {
         this.yRotation = yRotation;
         UpdateRotation();
     }
 }
예제 #4
0
        public override void PointClickMovement(Vector3 position)
        {
            if (!CacheEntity.CanMove())
            {
                return;
            }

            switch (CacheEntity.MovementSecure)
            {
            case MovementSecure.ServerAuthoritative:
                CallNetFunction(NetFuncPointClickMovement, FunctionReceivers.Server, position);
                break;

            case MovementSecure.NotSecure:
                tempMovementState = MovementState.Forward;
                SetMovePaths(position, true);
                break;
            }
        }
예제 #5
0
        public override void SetLookRotation(Quaternion rotation)
        {
            if (!CacheEntity.CanMove())
            {
                return;
            }

            switch (CacheEntity.MovementSecure)
            {
            case MovementSecure.ServerAuthoritative:
                // Cast to short to reduce packet size
                CallNetFunction(NetFuncUpdateYRotation, DeliveryMethod.Sequenced, FunctionReceivers.Server, (short)rotation.eulerAngles.y);
                break;

            case MovementSecure.NotSecure:
                if (!HasNavPaths)
                {
                    yRotation = rotation.eulerAngles.y;
                }
                break;
            }
        }
예제 #6
0
 protected void NetFuncKeyMovement(DirectionVector3 inputDirection, MovementState movementState)
 {
     if (!CacheEntity.CanMove())
     {
         return;
     }
     tempInputDirection = inputDirection;
     tempMovementState  = movementState;
     if (tempInputDirection.sqrMagnitude > 0)
     {
         navPaths = null;
     }
     if (canFly && !CacheOpenCharacterController.isGrounded && !isUnderWater && tempMovementState.HasFlag(MovementState.IsJump))
     {
         isFlying          = true;
         isJumping         = false;
         applyingJumpForce = false;
     }
     if (!isJumping && !applyingJumpForce)
     {
         isJumping = (CacheOpenCharacterController.isGrounded || isUnderWater) && tempMovementState.HasFlag(MovementState.IsJump);
     }
 }
예제 #7
0
        private void UpdateMovement(float deltaTime)
        {
            tempMoveVelocity   = Vector3.zero;
            tempMoveDirection  = Vector3.zero;
            tempTargetDistance = 0f;

            // Update airborne elasped
            if (CacheOpenCharacterController.isGrounded)
            {
                airborneElapsed = 0f;
            }
            else
            {
                airborneElapsed += deltaTime;
            }

            bool isGrounded = CacheOpenCharacterController.isGrounded || airborneElapsed < airborneDelay;

            if (isGrounded || !canFly)
            {
                isFlying = false;
            }

            if (HasNavPaths)
            {
                // Set `tempTargetPosition` and `tempCurrentPosition`
                tempTargetPosition    = navPaths.Peek();
                tempCurrentPosition   = CacheTransform.position;
                tempTargetPosition.y  = 0;
                tempCurrentPosition.y = 0;
                tempMoveDirection     = tempTargetPosition - tempCurrentPosition;
                tempMoveDirection.Normalize();
                tempTargetDistance = Vector3.Distance(tempTargetPosition, tempCurrentPosition);
                if (tempTargetDistance < StoppingDistance)
                {
                    navPaths.Dequeue();
                    if (!HasNavPaths)
                    {
                        StopMove();
                    }
                }
                else
                {
                    // Turn character to destination
                    yRotation = Quaternion.LookRotation(tempMoveDirection).eulerAngles.y;
                }
            }

            // If move by WASD keys, set move direction to input direction
            if (tempInputDirection.sqrMagnitude > 0f)
            {
                tempMoveDirection = tempInputDirection;
                tempMoveDirection.Normalize();
            }

            if (!CacheEntity.CanMove())
            {
                tempMoveDirection = Vector3.zero;
                isJumping         = false;
                applyingJumpForce = false;
            }

            // Prepare movement speed
            tempEntityMoveSpeed = applyingJumpForce ? 0f : CacheEntity.GetMoveSpeed();
            if (isUnderWater)
            {
                isFlying = false;
            }
            tempCurrentMoveSpeed = tempEntityMoveSpeed * (isFlying ? flySpeed : isUnderWater ? swimSpeed : 1f);
            // Calculate vertical velocity by gravity
            if (!isGrounded && !isFlying)
            {
                if (!isUnderWater || submergence <= underWaterThreshold)
                {
                    if (!useRootMotionForFall)
                    {
                        tempVerticalVelocity = Mathf.MoveTowards(tempVerticalVelocity, -maxFallVelocity, gravity * deltaTime);
                    }
                    else
                    {
                        tempVerticalVelocity = 0f;
                    }
                }
                else
                {
                    tempVerticalVelocity = 0f;
                }
            }
            else
            {
                tempVerticalVelocity = 0f;
            }

            // Jumping
            if (!isFlying && (isUnderWater || isGrounded) && isJumping)
            {
                if (!isUnderWater || submergence <= underWaterThreshold)
                {
                    airborneElapsed = airborneDelay;
                    CacheEntity.CallAllPlayJumpAnimation();
                    applyingJumpForce       = true;
                    applyJumpForceCountDown = 0f;
                    switch (applyJumpForceMode)
                    {
                    case ApplyJumpForceMode.ApplyAfterFixedDuration:
                        applyJumpForceCountDown = applyJumpForceFixedDuration;
                        break;

                    case ApplyJumpForceMode.ApplyAfterJumpDuration:
                        if (CacheEntity.Model is IJumppableModel)
                        {
                            applyJumpForceCountDown = (CacheEntity.Model as IJumppableModel).GetJumpAnimationDuration();
                        }
                        break;
                    }
                }
            }

            if (applyingJumpForce)
            {
                applyJumpForceCountDown -= Time.deltaTime;
                if (applyJumpForceCountDown <= 0f)
                {
                    applyingJumpForce = false;
                    if (!useRootMotionForJump)
                    {
                        tempVerticalVelocity = CalculateJumpVerticalSpeed();
                    }
                }
            }
            // Updating horizontal movement (WASD inputs)
            if (tempMoveDirection.sqrMagnitude > 0f)
            {
                // Calculate only horizontal move direction
                tempHorizontalMoveDirection   = tempMoveDirection;
                tempHorizontalMoveDirection.y = 0;
                tempHorizontalMoveDirection.Normalize();

                // If character move backward
                if (Vector3.Angle(tempHorizontalMoveDirection, CacheTransform.forward) > 120)
                {
                    tempCurrentMoveSpeed *= backwardMoveSpeedRate;
                }

                if (HasNavPaths)
                {
                    // NOTE: `tempTargetPosition` and `tempCurrentPosition` were set above
                    tempSqrMagnitude        = (tempTargetPosition - tempCurrentPosition).sqrMagnitude;
                    tempPredictPosition     = tempCurrentPosition + (tempHorizontalMoveDirection * tempCurrentMoveSpeed * deltaTime);
                    tempPredictSqrMagnitude = (tempPredictPosition - tempCurrentPosition).sqrMagnitude;
                    // Check `tempSqrMagnitude` against the `tempPredictSqrMagnitude`
                    // if `tempPredictSqrMagnitude` is greater than `tempSqrMagnitude`,
                    // rigidbody will reaching target and character is moving pass it,
                    // so adjust move speed by distance and time (with physic formula: v=s/t)
                    if (tempPredictSqrMagnitude >= tempSqrMagnitude)
                    {
                        tempCurrentMoveSpeed *= tempTargetDistance / deltaTime / tempCurrentMoveSpeed;
                    }
                    tempMoveVelocity = tempHorizontalMoveDirection * tempCurrentMoveSpeed;
                }
                else
                {
                    // Move with wasd keys so it does not have to adjust speed
                    tempMoveVelocity = tempHorizontalMoveDirection * tempCurrentMoveSpeed;
                }
            }

            // Updating vertical movement (Fall, WASD inputs under water)
            if (isUnderWater || isFlying)
            {
                if (submergence >= underWaterThreshold || shouldDive || isFlying)
                {
                    tempMoveVelocity.y = tempMoveDirection.y * tempCurrentMoveSpeed;
                    shouldDive         = false;
                }
                else
                {
                    float distanceFromThreshold = underWaterThreshold - submergence;
                    float bouyantVelocity       = 0.01f;
                    if (distanceFromThreshold > 0.01)
                    {
                        bouyantVelocity = -(distanceFromThreshold / deltaTime / tempCurrentMoveSpeed);
                    }
                    tempMoveVelocity.y = bouyantVelocity + (tempVerticalVelocity > 0 ? tempVerticalVelocity : 0f);
                }
                if (InputManager.GetButton("Crouch") || tempMoveDirection.y < -0.8)
                {
                    shouldDive = true;
                }
            }
            else
            {
                // Update velocity while not under water
                tempMoveVelocity.y = tempVerticalVelocity;
            }

            collisionFlags = CacheOpenCharacterController.Move(tempMoveVelocity * deltaTime);
            if ((collisionFlags & CollisionFlags.CollidedBelow) == CollisionFlags.CollidedBelow ||
                (collisionFlags & CollisionFlags.CollidedAbove) == CollisionFlags.CollidedAbove)
            {
                // Hit something below or above, falling in next frame
                tempVerticalVelocity = 0f;
            }

            UpdateRotation();
            isJumping = false;
        }