CharacterControllerLogic.IsInPivot C# (CSharp) Method

IsInPivot() public method

public IsInPivot ( ) : bool
return bool
    public bool IsInPivot()
    {
        return stateInfo.nameHash == m_LocomotionPivotLId ||
            stateInfo.nameHash == m_LocomotionPivotRId ||
            transInfo.nameHash == m_LocomotionPivotLTransId ||
            transInfo.nameHash == m_LocomotionPivotRTransId;
    }

Usage Example

    void LateUpdate()
    {
        // Pull values from controller/keyboard
        float rightX = Input.GetAxis("RightStickX");
        float rightY = Input.GetAxis("RightStickY");
        float leftX  = Input.GetAxis("Horizontal");
        float leftY  = Input.GetAxis("Vertical");

        Vector3 characterOffset = followXform.position + new Vector3(0f, distanceUp, 0f);
        Vector3 lookAt          = characterOffset;
        Vector3 targetPosition  = Vector3.zero;

        // Determine camera state
        // * Targeting *
        if (Input.GetAxis("Target") > TARGETING_THRESHOLD)
        {
            barEffect.coverage = Mathf.SmoothStep(barEffect.coverage, widescreen, targetingTime);

            camState = CamStates.Target;
        }
        else
        {
            barEffect.coverage = Mathf.SmoothStep(barEffect.coverage, 0f, targetingTime);

            // * First Person *
            if (rightY > firstPersonThreshold && camState != CamStates.Free && camState != CamStates.Free && !follow.IsInLocomotion())
            {
                // Reset look before entering the first person mode
                xAxisRot   = 0;
                lookWeight = 0f;
                camState   = CamStates.FirstPerson;
            }

            if (rightY < freeThreshold && System.Math.Round(follow.Speed, 2) == 0)
            {
                camState       = CamStates.Free;
                savedRigToGoal = Vector3.zero;
            }

            // * Behind the back *
            if ((camState == CamStates.FirstPerson && Input.GetButton("ExitFPV")) ||
                (camState == CamStates.Target && (Input.GetAxis("Target") <= TARGETING_THRESHOLD)))
            {
                camState = CamStates.Behind;
            }
        }

        // Set the Look At Weight - amount to use look at IK vs using the head's animation
        follow.Animator.SetLookAtWeight(lookWeight);

        // Execute camera state
        switch (camState)
        {
        case CamStates.Behind:
            ResetCamera();

            // Only update camera look direction if moving
            if (follow.Speed > follow.LocomotionThreshold && follow.IsInLocomotion() && !follow.IsInPivot())
            {
                lookDir = Vector3.Lerp(followXform.right * (leftX < 0 ? 1f : -1f), followXform.forward * (leftY < 0 ? -1f : 1f), Mathf.Abs(Vector3.Dot(this.transform.forward, followXform.forward)));
                Debug.DrawRay(this.transform.position, lookDir, Color.white);

                // Calculate direction from camera to player, kill Y, and normalize to give a valid direction with unit magnitude
                curLookDir   = Vector3.Normalize(characterOffset - this.transform.position);
                curLookDir.y = 0;
                Debug.DrawRay(this.transform.position, curLookDir, Color.green);

                // Damping makes it so we don't update targetPosition while pivoting; camera shouldn't rotate around player
                curLookDir = Vector3.SmoothDamp(curLookDir, lookDir, ref velocityLookDir, lookDirDampTime);
            }

            targetPosition = characterOffset + followXform.up * distanceUp - Vector3.Normalize(curLookDir) * distanceAway;
            Debug.DrawLine(followXform.position, targetPosition, Color.magenta);

            break;

        case CamStates.Target:
            ResetCamera();
            lookDir    = followXform.forward;
            curLookDir = followXform.forward;

            targetPosition = characterOffset + followXform.up * distanceUp - lookDir * distanceAway;

            break;

        case CamStates.FirstPerson:
            // Looking up and down
            // Calculate the amount of rotation and apply to the firstPersonCamPos GameObject
            xAxisRot += (-leftY * 0.5f * firstPersonLookSpeed);
            xAxisRot  = Mathf.Clamp(xAxisRot, firstPersonXAxisClamp.x, firstPersonXAxisClamp.y);
            firstPersonCamPos.XForm.localRotation = Quaternion.Euler(xAxisRot, 0, 0);

            // Superimpose firstPersonCamPos GameObject's rotation on camera
            Quaternion rotationShift = Quaternion.FromToRotation(this.transform.forward, firstPersonCamPos.XForm.forward);
            this.transform.rotation = rotationShift * this.transform.rotation;

            // Move character model's head
            follow.Animator.SetLookAtPosition(firstPersonCamPos.XForm.position + firstPersonCamPos.XForm.forward);
            lookWeight = Mathf.Lerp(lookWeight, 1.0f, Time.deltaTime * firstPersonLookSpeed);


            // Looking left and right
            // Similarly to how character is rotated while in locomotion, use Quaternion * to add rotation to character
            Vector3    rotationAmount = Vector3.Lerp(Vector3.zero, new Vector3(0f, fPSRotationDegreePerSecond * (leftX < 0f ? -1f : 1f), 0f), Mathf.Abs(leftX));
            Quaternion deltaRotation  = Quaternion.Euler(rotationAmount * Time.deltaTime);
            follow.transform.rotation = (follow.transform.rotation * deltaRotation);

            // Move camera to firstPersonCamPos
            targetPosition = firstPersonCamPos.XForm.position;

            // Smoothly transition look direction towards firstPersonCamPos when entering first person mode
            lookAt = Vector3.Lerp(targetPosition + followXform.forward, this.transform.position + this.transform.forward, camSmoothDampTime * Time.deltaTime);
            Debug.DrawRay(Vector3.zero, lookAt, Color.black);
            Debug.DrawRay(Vector3.zero, targetPosition + followXform.forward, Color.white);
            Debug.DrawRay(Vector3.zero, firstPersonCamPos.XForm.position + firstPersonCamPos.XForm.forward, Color.cyan);

            // Choose lookAt target based on distance
            lookAt = (Vector3.Lerp(this.transform.position + this.transform.forward, lookAt, Vector3.Distance(this.transform.position, firstPersonCamPos.XForm.position)));
            break;

        case CamStates.Free:
            lookWeight = Mathf.Lerp(lookWeight, 0.0f, Time.deltaTime * firstPersonLookSpeed);

            // Move height and distance from character in separate parentRig transform since RotateAround has control of both position and rotation
            Vector3 rigToGoalDirection = Vector3.Normalize(characterOffset - this.transform.position);
            // Can't calculate distanceAway from a vector with Y axis rotation in it; zero it out
            rigToGoalDirection.y = 0f;

            Vector3 rigToGoal = characterOffset - parentRig.position;
            rigToGoal.y = 0;
            Debug.DrawRay(parentRig.transform.position, rigToGoal, Color.red);

            // Panning in and out
            // If statement works for positive values; don't tween if stick not increasing in either direction; also don't tween if user is rotating
            // Checked against rightStickThreshold because very small values for rightY mess up the Lerp function
            if (rightY < -1f * rightStickThreshold && rightY <= rightStickPrevFrame.y && Mathf.Abs(rightX) < rightStickThreshold)
            {
                distanceUpFree   = Mathf.Lerp(distanceUp, distanceUp * distanceUpMultiplier, Mathf.Abs(rightY));
                distanceAwayFree = Mathf.Lerp(distanceAway, distanceAway * distanceAwayMultipler, Mathf.Abs(rightY));
                targetPosition   = characterOffset + followXform.up * distanceUpFree - rigToGoalDirection * distanceAwayFree;
            }
            else if (rightY > rightStickThreshold && rightY >= rightStickPrevFrame.y && Mathf.Abs(rightX) < rightStickThreshold)
            {
                // Subtract height of camera from height of player to find Y distance
                distanceUpFree = Mathf.Lerp(Mathf.Abs(transform.position.y - characterOffset.y), camMinDistFromChar.y, rightY);
                // Use magnitude function to find X distance
                distanceAwayFree = Mathf.Lerp(rigToGoal.magnitude, camMinDistFromChar.x, rightY);

                targetPosition = characterOffset + followXform.up * distanceUpFree - rigToGoalDirection * distanceAwayFree;
            }

            // Store direction only if right stick inactive
            if (rightX != 0 || rightY != 0)
            {
                savedRigToGoal = rigToGoalDirection;
            }


            // Rotating around character
            parentRig.RotateAround(characterOffset, followXform.up, freeRotationDegreePerSecond * (Mathf.Abs(rightX) > rightStickThreshold ? rightX : 0f));

            // Still need to track camera behind player even if they aren't using the right stick; achieve this by saving distanceAwayFree every frame
            if (targetPosition == Vector3.zero)
            {
                targetPosition = characterOffset + followXform.up * distanceUpFree - savedRigToGoal * distanceAwayFree;
            }

//				SmoothPosition(transform.position, targetPosition);
//				transform.LookAt(lookAt);
            break;
        }


//		if (camState != CamStates.Free)
//		{
        CompensateForWalls(characterOffset, ref targetPosition);

        SmoothPosition(parentRig.position, targetPosition);

        transform.LookAt(lookAt);
//		}

        rightStickPrevFrame = new Vector2(rightX, rightY);
    }