/// <summary>
 /// (Called by KinematicCharacterMotor during its update cycle)
 /// This is called before the character begins its movement update
 /// </summary>
 public override void BeforeCharacterUpdate(float deltaTime)
 {
     // Handle detecting water surfaces
     {
         // Do a character overlap test to detect water surfaces
         if (Motor.CharacterOverlap(Motor.TransientPosition, Motor.TransientRotation, _probedColliders, WaterLayer, QueryTriggerInteraction.Collide) > 0)
         {
             // If a water surface was detected
             if (_probedColliders[0] != null)
             {
                 // If the swimming reference point is inside the box, make sure we are in swimming state
                 if (Physics.ClosestPoint(SwimmingReferencePoint.position, _probedColliders[0], _probedColliders[0].transform.position, _probedColliders[0].transform.rotation) == SwimmingReferencePoint.position)
                 {
                     if (CurrentCharacterState == CharacterState.Default)
                     {
                         TransitionToState(CharacterState.Swimming);
                         _waterZone = _probedColliders[0];
                     }
                 }
                 // otherwise; default state
                 else
                 {
                     if (CurrentCharacterState == CharacterState.Swimming)
                     {
                         TransitionToState(CharacterState.Default);
                     }
                 }
             }
         }
     }
 }
Beispiel #2
0
        /// <summary>
        /// (Called by KinematicCharacterMotor during its update cycle)
        /// This is called after the character has finished its movement update
        /// </summary>
        public override void AfterCharacterUpdate(float deltaTime)
        {
            switch (CurrentCharacterState)
            {
            case CharacterState.Default:
            {
                // Handle jump-related values
                {
                    // Handle jumping pre-ground grace period
                    if (_jumpRequested && _timeSinceJumpRequested > JumpPreGroundingGraceTime)
                    {
                        _jumpRequested = false;
                    }

                    if (AllowJumpingWhenSliding ? Motor.GroundingStatus.FoundAnyGround : Motor.GroundingStatus.IsStableOnGround)
                    {
                        // If we're on a ground surface, reset jumping values
                        if (!_jumpedThisFrame)
                        {
                            _jumpConsumed = false;
                        }
                        _timeSinceLastAbleToJump = 0f;
                    }
                    else
                    {
                        // Keep track of time since we were last able to jump (for grace period)
                        _timeSinceLastAbleToJump += deltaTime;
                    }
                }

                // Handle uncrouching
                if (_isCrouching && !_shouldBeCrouching)
                {
                    // Do an overlap test with the character's standing height to see if there are any obstructions
                    Motor.SetCapsuleDimensions(0.5f, 2f, 1f);
                    if (Motor.CharacterOverlap(
                            Motor.TransientPosition,
                            Motor.TransientRotation,
                            _probedColliders,
                            Motor.CollidableLayers,
                            QueryTriggerInteraction.Ignore) > 0)
                    {
                        // If obstructions, just stick to crouching dimensions
                        Motor.SetCapsuleDimensions(0.5f, 1f, 0.5f);
                    }
                    else
                    {
                        // If no obstructions, uncrouch
                        MeshRoot.localScale = new Vector3(1f, 1f, 1f);
                        _isCrouching        = false;
                    }
                }


                break;
            }
            }
        }
Beispiel #3
0
    public override void AfterCharacterUpdate(float deltaTime)
    {
        // Handle jumping pre-ground grace period
        if (jumpRequested && timeSinceJumpRequested > JumpPreGroundingGraceTime)
        {
            jumpRequested = false;
        }

        if (AllowJumpingWhenSliding ? Motor.GroundingStatus.FoundAnyGround : Motor.GroundingStatus.IsStableOnGround)
        {
            // If we're on a ground surface, reset jumping values
            if (!jumpedThisFrame)
            {
                doubleJumpConsumed = false;
                jumpConsumed       = false;
            }

            timeSinceLastAbleToJump = 0f;
        }
        else
        {
            // Keep track of time since we were last able to jump (for grace period)
            timeSinceLastAbleToJump += deltaTime;
        }

        // Handle landing and leaving ground
        if (Motor.GroundingStatus.IsStableOnGround && !Motor.LastGroundingStatus.IsStableOnGround)
        {
            OnLanded();
        }
        else if (!Motor.GroundingStatus.IsStableOnGround && Motor.LastGroundingStatus.IsStableOnGround)
        {
            OnLeaveStableGround();
        }

        // Handle uncrouching
        if (IsCrouching && !shouldBeCrouching)
        {
            // Do an overlap test with the character's standing height to see if there are any obstructions
            Motor.SetCapsuleDimensions(C.BaseCharacterRadius, C.BaseCharacterHeight, 0f);
            if (Motor.CharacterOverlap(
                    Motor.TransientPosition,
                    Motor.TransientRotation,
                    probedColliders,
                    Motor.CollidableLayers,
                    QueryTriggerInteraction.Ignore) > 0)
            {
                // If obstructions, just stick to crouching dimensions
                Motor.SetCapsuleDimensions(C.BaseCharacterRadius, C.BaseCharacterHeight, C.BaseCharacterHeight / 2f);
            }
            else
            {
                // If no obstructions, uncrouch
                C.MeshRoot.localScale = new Vector3(1f, 1f, 1f);
                IsCrouching           = false;
            }
        }
    }
Beispiel #4
0
        /// <summary>
        /// (Called by KinematicCharacterMotor during its update cycle)
        /// This is called after the character has finished its movement update
        /// </summary>
        public override void AfterCharacterUpdate(float deltaTime)
        {
            switch (CurrentCharacterState)
            {
            case CharacterState.Default:
            {
                // Handle jump-related values
                {
                    // Handle jumping pre-ground grace period
                    if (_jumpRequested && _timeSinceJumpRequested > JumpPreGroundingGraceTime)
                    {
                        _jumpRequested = false;
                    }

                    if (AllowJumpingWhenSliding ? Motor.GroundingStatus.FoundAnyGround : Motor.GroundingStatus.IsStableOnGround)
                    {
                        // If we're on a ground surface, reset jumping values
                        if (!_jumpedThisFrame)
                        {
                            _doubleJumpConsumed = false;
                            _jumpConsumed       = false;
                        }
                        _timeSinceLastAbleToJump = 0f;
                    }
                    else
                    {
                        // Keep track of time since we were last able to jump (for grace period)
                        _timeSinceLastAbleToJump += deltaTime;
                    }
                }

                // Handle uncrouching
                if (_isCrouching && !_shouldBeCrouching)
                {
                    // Do an overlap test with the character's standing height to see if there are any obstructions
                    Motor.SetCapsuleDimensions(0.5f, 2f, 1f);
                    if (Motor.CharacterOverlap(
                            Motor.TransientPosition,
                            Motor.TransientRotation,
                            _probedColliders,
                            Motor.CollidableLayers,
                            QueryTriggerInteraction.Ignore) > 0)
                    {
                        // If obstructions, just stick to crouching dimensions
                        Motor.SetCapsuleDimensions(0.5f, 1f, 0.5f);
                    }
                    else
                    {
                        // If no obstructions, uncrouch
                        MeshRoot.localScale = new Vector3(1f, 1f, 1f);
                        _isCrouching        = false;
                    }
                }
                break;
            }

            case CharacterState.Climbing:
            {
                switch (_climbingState)
                {
                case ClimbingState.Climbing:
                    // Detect getting off ladder during climbing
                    _activeLadder.ClosestPointOnLadderSegment(Motor.TransientPosition, out _onLadderSegmentState);
                    if (Mathf.Abs(_onLadderSegmentState) > 0.05f)
                    {
                        _climbingState = ClimbingState.DeAnchoring;

                        // If we're higher than the ladder top point
                        if (_onLadderSegmentState > 0)
                        {
                            _ladderTargetPosition = _activeLadder.TopReleasePoint.position;
                            _ladderTargetRotation = _activeLadder.TopReleasePoint.rotation;
                        }
                        // If we're lower than the ladder bottom point
                        else if (_onLadderSegmentState < 0)
                        {
                            _ladderTargetPosition = _activeLadder.BottomReleasePoint.position;
                            _ladderTargetRotation = _activeLadder.BottomReleasePoint.rotation;
                        }
                    }
                    break;

                case ClimbingState.Anchoring:
                case ClimbingState.DeAnchoring:
                    // Detect transitioning out from anchoring states
                    if (_anchoringTimer >= AnchoringDuration)
                    {
                        if (_climbingState == ClimbingState.Anchoring)
                        {
                            _climbingState = ClimbingState.Climbing;
                        }
                        else if (_climbingState == ClimbingState.DeAnchoring)
                        {
                            TransitionToState(CharacterState.Default);
                        }
                    }

                    // Keep track of time since we started anchoring
                    _anchoringTimer += deltaTime;
                    break;
                }
                break;
            }
            }
        }
Beispiel #5
0
        /// <summary>
        /// This is called every frame by MyPlayer in order to tell the character what its inputs are
        /// </summary>
        public void SetInputs(ref PlayerCharacterInputs inputs)
        {
            // Handle ladder transitions
            _ladderUpDownInput = inputs.MoveAxisForward;
            if (inputs.ClimbLadder)
            {
                if (Motor.CharacterOverlap(Motor.TransientPosition, Motor.TransientRotation, _probedColliders, InteractionLayer, QueryTriggerInteraction.Collide) > 0)
                {
                    if (_probedColliders[0] != null)
                    {
                        // Handle ladders
                        MyLadder ladder = _probedColliders[0].gameObject.GetComponent <MyLadder>();
                        if (ladder)
                        {
                            // Transition to ladder climbing state
                            if (CurrentCharacterState == CharacterState.Default)
                            {
                                _activeLadder = ladder;
                                TransitionToState(CharacterState.Climbing);
                            }
                            // Transition back to default movement state
                            else if (CurrentCharacterState == CharacterState.Climbing)
                            {
                                _climbingState        = ClimbingState.DeAnchoring;
                                _ladderTargetPosition = Motor.TransientPosition;
                                _ladderTargetRotation = _rotationBeforeClimbing;
                            }
                        }
                    }
                }
            }

            // Clamp input
            Vector3 moveInputVector = Vector3.ClampMagnitude(new Vector3(inputs.MoveAxisRight, 0f, inputs.MoveAxisForward), 1f);

            // Calculate camera direction and rotation on the character plane
            Vector3 cameraPlanarDirection = Vector3.ProjectOnPlane(inputs.CameraRotation * Vector3.forward, Motor.CharacterUp).normalized;

            if (cameraPlanarDirection.sqrMagnitude == 0f)
            {
                cameraPlanarDirection = Vector3.ProjectOnPlane(inputs.CameraRotation * Vector3.up, Motor.CharacterUp).normalized;
            }
            Quaternion cameraPlanarRotation = Quaternion.LookRotation(cameraPlanarDirection, Motor.CharacterUp);

            switch (CurrentCharacterState)
            {
            case CharacterState.Default:
            {
                // Move and look inputs
                _moveInputVector = cameraPlanarRotation * moveInputVector;
                _lookInputVector = cameraPlanarDirection;

                // Jumping input
                if (inputs.JumpDown)
                {
                    _timeSinceJumpRequested = 0f;
                    _jumpRequested          = true;
                }

                // Crouching input
                if (inputs.CrouchDown)
                {
                    _shouldBeCrouching = true;

                    if (!_isCrouching)
                    {
                        _isCrouching = true;
                        Motor.SetCapsuleDimensions(0.5f, 1f, 0.5f);
                        MeshRoot.localScale = new Vector3(1f, 0.5f, 1f);
                    }
                }
                else if (inputs.CrouchUp)
                {
                    _shouldBeCrouching = false;
                }
                break;
            }
            }
        }
Beispiel #6
0
        public override void AfterCharacterUpdate(float deltaTime)
        {
            // Handle jump-related values
            {
                // Handle jumping pre-ground grace period
                if (_jumpRequested && _timeSinceJumpRequested > JumpPreGroundingGraceTime)
                {
                    _jumpRequested = false;
                }

                if (AllowJumpingWhenSliding ? Motor.GroundingStatus.FoundAnyGround : Motor.GroundingStatus.IsStableOnGround)
                {
                    // If we're on a ground surface, reset jumping values
                    if (!_jumpedThisFrame)
                    {
                        _doubleJumpConsumed = false;
                        _jumpConsumed       = false;
                    }
                    _timeSinceLastAbleToJump = 0f;
                }
                else
                {
                    // Keep track of time since we were last able to jump (for grace period)
                    _timeSinceLastAbleToJump += deltaTime;
                }
            }

            // Grounding considerations
            if (Motor.GroundingStatus.IsStableOnGround && !Motor.LastGroundingStatus.IsStableOnGround)
            {
                if (!IsPreFrameMustUnground)
                {
                    Callback_OnLanded?.Invoke();
                }
                IsPreFrameMustUnground = false;
                if (IsJumped)
                {
                    Callback_OnJumpLanded?.Invoke();
                }
                IsJumped        = false;
                IsDoubbleJumped = false;
            }
            else if (!Motor.GroundingStatus.IsStableOnGround && Motor.LastGroundingStatus.IsStableOnGround)
            {
                Callback_OnLeaveStableGround?.Invoke();
            }

            if (AllowJumpingWhenSliding ? Motor.GroundingStatus.FoundAnyGround : Motor.GroundingStatus.IsStableOnGround)
            {
                //_jumpConsumed = false;
                _timeSinceLastAbleToJump = 0f;
            }
            else
            {
                _timeSinceLastAbleToJump += deltaTime;
            }

            // Handle uncrouching
            if (_isTryingToUncrouch)
            {
                // Do an overlap test with the character's standing height to see if there are any obstructions
                SetDimensions(Radius, Height);
                if (Motor.CharacterOverlap(
                        Motor.TransientPosition,
                        Motor.TransientRotation,
                        _probedColliders,
                        Motor.CollidableLayers,
                        QueryTriggerInteraction.Ignore) > 0)
                {
                    // If obstructions, just stick to crouching dimensions
                    SetDimensions(Radius, HalfHeight);
                }
                else
                {
                    // If no obstructions, uncrouch
                    //MeshRoot.localScale = new Vector3(1f, 1f, 1f);

                    _isTryingToUncrouch = false;
                }
            }

            // Reset root motion deltas
            RootMotionPositionDelta = Vector3.zero;
            RootMotionRotationDelta = Quaternion.identity;
        }