< Summary

Class:DCLCharacterController
Assembly:CharacterController
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/CharacterController/DCLCharacterController.cs
Covered lines:197
Uncovered lines:60
Coverable lines:257
Total lines:592
Line coverage:76.6% (197 of 257)
Covered branches:0
Total branches:0
Covered methods:36
Total methods:42
Method coverage:85.7% (36 of 42)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
DCLCharacterController()0%110100%
SetMovementInputToZero()0%2100%
Awake()0%44096.3%
SubscribeToInput()0%110100%
OnDestroy()0%110100%
OnWorldReposition(...)0%330100%
SetPosition(...)0%990100%
Teleport(...)0%110100%
Teleport(...)0%3.033085.71%
SetPosition(...)0%2100%
SetEnabled(...)0%110100%
Moved(...)0%220100%
LateUpdate()0%42.8629074.55%
SaveLateUpdateGroundTransforms()0%6200%
Jump()0%12300%
ResetGround()0%2.022083.33%
CheckGround()0%48.3815047.06%
CastGroundCheckingRays()0%220100%
CastGroundCheckingRays(...)0%220100%
CastGroundCheckingRay(...)0%2100%
CastGroundCheckingRays(...)0%660100%
CastGroundCheckingRay(...)0%220100%
ReportMovement()0%330100%
PauseGravity()0%110100%
ResumeGravity()0%2100%
OnRenderingStateChanged(...)0%220100%
IsLastCollisionGround()0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/CharacterController/DCLCharacterController.cs

#LineLine coverage
 1using Cinemachine;
 2using DCL;
 3using DCL.Configuration;
 4using DCL.Helpers;
 5using DCL.Interface;
 6using System;
 7using UnityEngine;
 8using Environment = DCL.Environment;
 9
 10public class DCLCharacterController : MonoBehaviour
 11{
 830012    public static DCLCharacterController i { get; private set; }
 13
 14    private const float CONTROLLER_DRIFT_OFFSET = 0.15f;
 15
 16    [Header("Movement")]
 34117    public float minimumYPosition = 1f;
 18
 34119    public float groundCheckExtraDistance = 0.1f;
 34120    public float gravity = -55f;
 34121    public float jumpForce = 12f;
 34122    public float movementSpeed = 8f;
 34123    public float runningSpeedMultiplier = 2f;
 24
 25    public DCLCharacterPosition characterPosition;
 26
 27    [Header("Collisions")]
 28    public LayerMask groundLayers;
 29
 30    [Header("Additional Camera Layers")]
 31    public LayerMask cameraLayers;
 32
 33    [NonSerialized]
 34    public bool initialPositionAlreadySet = false;
 35
 36    [NonSerialized]
 34137    public bool characterAlwaysEnabled = true;
 38
 39    [NonSerialized]
 40    public CharacterController characterController;
 41
 42    FreeMovementController freeMovementController;
 43
 44    new Collider collider;
 45
 46    float lastUngroundedTime = 0f;
 47    float lastJumpButtonPressedTime = 0f;
 48    float lastMovementReportTime;
 49    float originalGravity;
 50    Vector3 lastLocalGroundPosition;
 51
 52    Vector3 lastCharacterRotation;
 53    Vector3 lastGlobalCharacterRotation;
 54
 34155    Vector3 velocity = Vector3.zero;
 56
 3457    public bool isWalking { get; private set; } = false;
 3458    public bool isMovingByUserInput { get; private set; } = false;
 640159    public bool isJumping { get; private set; } = false;
 2958460    public bool isGrounded { get; private set; }
 3506661    public bool isOnMovingPlatform { get; private set; }
 62
 63    internal Transform groundTransform;
 64
 65    Vector3 lastPosition;
 66    Vector3 groundLastPosition;
 67    Quaternion groundLastRotation;
 68    bool jumpButtonPressed = false;
 69
 70    [Header("InputActions")]
 71    public InputAction_Hold jumpAction;
 72
 73    public InputAction_Hold sprintAction;
 74
 75    public Vector3 moveVelocity;
 76
 77    private InputAction_Hold.Started jumpStartedDelegate;
 78    private InputAction_Hold.Finished jumpFinishedDelegate;
 79    private InputAction_Hold.Started walkStartedDelegate;
 80    private InputAction_Hold.Finished walkFinishedDelegate;
 81
 1155282    private Vector3NullableVariable characterForward => CommonScriptableObjects.characterForward;
 83
 84    public static Action<DCLCharacterPosition> OnCharacterMoved;
 85    public static Action<DCLCharacterPosition> OnPositionSet;
 86    public event Action<float> OnUpdateFinish;
 87
 88    public GameObject avatarGameObject;
 89    public GameObject firstPersonCameraGameObject;
 90
 91    [SerializeField]
 92    private InputAction_Measurable characterYAxis;
 93
 94    [SerializeField]
 95    private InputAction_Measurable characterXAxis;
 96
 1092397    private Vector3Variable cameraForward => CommonScriptableObjects.cameraForward;
 3498    private Vector3Variable cameraRight => CommonScriptableObjects.cameraRight;
 99
 341100    private readonly DataStore_Player dataStorePlayer = DataStore.i.player;
 101
 102    [NonSerialized]
 103    public float movingPlatformSpeed;
 104    private CollisionFlags lastCharacterControllerCollision;
 105
 106    public event Action OnJump;
 107    public event Action OnHitGround;
 108    public event Action<float> OnMoved;
 109
 110    public void SetMovementInputToZero()
 111    {
 0112        characterXAxis.SetValue(0);
 0113        characterYAxis.SetValue(0);
 0114    }
 115
 116    void Awake()
 117    {
 324118        if (i != null)
 119        {
 22120            Destroy(gameObject);
 22121            return;
 122        }
 123
 302124        i = this;
 302125        originalGravity = gravity;
 126
 302127        SubscribeToInput();
 302128        CommonScriptableObjects.playerUnityPosition.Set(Vector3.zero);
 302129        dataStorePlayer.playerWorldPosition.Set(Vector3.zero);
 302130        CommonScriptableObjects.playerCoords.Set(Vector2Int.zero);
 302131        dataStorePlayer.playerGridPosition.Set(Vector2Int.zero);
 302132        CommonScriptableObjects.playerUnityEulerAngles.Set(Vector3.zero);
 133
 302134        characterPosition = new DCLCharacterPosition();
 302135        characterController = GetComponent<CharacterController>();
 302136        freeMovementController = GetComponent<FreeMovementController>();
 302137        collider = GetComponent<Collider>();
 138
 302139        CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 140
 302141        lastPosition = transform.position;
 302142        transform.parent = null;
 143
 302144        CommonScriptableObjects.rendererState.OnChange += OnRenderingStateChanged;
 302145        OnRenderingStateChanged(CommonScriptableObjects.rendererState.Get(), false);
 146
 302147        if (avatarGameObject == null || firstPersonCameraGameObject == null)
 148        {
 0149            throw new Exception("Both the avatar and first person camera game objects must be set.");
 150        }
 151
 302152        var worldData = DataStore.i.Get<DataStore_World>();
 302153        worldData.avatarTransform.Set(avatarGameObject.transform);
 302154        worldData.fpsTransform.Set(firstPersonCameraGameObject.transform);
 155
 302156        dataStorePlayer.lastTeleportPosition.OnChange += Teleport;
 302157    }
 158
 159    private void SubscribeToInput()
 160    {
 302161        jumpStartedDelegate = (action) =>
 162        {
 0163            lastJumpButtonPressedTime = Time.time;
 0164            jumpButtonPressed = true;
 0165        };
 302166        jumpFinishedDelegate = (action) => jumpButtonPressed = false;
 302167        jumpAction.OnStarted += jumpStartedDelegate;
 302168        jumpAction.OnFinished += jumpFinishedDelegate;
 169
 302170        walkStartedDelegate = (action) => isWalking = true;
 302171        walkFinishedDelegate = (action) => isWalking = false;
 302172        sprintAction.OnStarted += walkStartedDelegate;
 302173        sprintAction.OnFinished += walkFinishedDelegate;
 302174    }
 175
 176    void OnDestroy()
 177    {
 324178        CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 324179        jumpAction.OnStarted -= jumpStartedDelegate;
 324180        jumpAction.OnFinished -= jumpFinishedDelegate;
 324181        sprintAction.OnStarted -= walkStartedDelegate;
 324182        sprintAction.OnFinished -= walkFinishedDelegate;
 324183        CommonScriptableObjects.rendererState.OnChange -= OnRenderingStateChanged;
 324184        dataStorePlayer.lastTeleportPosition.OnChange -= Teleport;
 324185        i = null;
 324186    }
 187
 188    void OnWorldReposition(Vector3 current, Vector3 previous)
 189    {
 2190        Vector3 oldPos = this.transform.position;
 2191        this.transform.position = characterPosition.unityPosition; //CommonScriptableObjects.playerUnityPosition;
 192
 2193        if (CinemachineCore.Instance.BrainCount > 0)
 194        {
 2195            CinemachineCore.Instance.GetActiveBrain(0).ActiveVirtualCamera?.OnTargetObjectWarped(transform, transform.po
 196        }
 2197    }
 198
 199    public void SetPosition(Vector3 newPosition)
 200    {
 201        // failsafe in case something teleports the player below ground collisions
 6093202        if (newPosition.y < minimumYPosition)
 203        {
 75204            newPosition.y = minimumYPosition + 2f;
 205        }
 206
 6093207        lastPosition = characterPosition.worldPosition;
 6093208        characterPosition.worldPosition = newPosition;
 6093209        transform.position = characterPosition.unityPosition;
 6093210        Environment.i.platform.physicsSyncController?.MarkDirty();
 211
 6093212        CommonScriptableObjects.playerUnityPosition.Set(characterPosition.unityPosition);
 6093213        dataStorePlayer.playerWorldPosition.Set(characterPosition.worldPosition);
 6093214        Vector2Int playerPosition = Utils.WorldToGridPosition(characterPosition.worldPosition);
 6093215        CommonScriptableObjects.playerCoords.Set(playerPosition);
 6093216        dataStorePlayer.playerGridPosition.Set(playerPosition);
 6093217        dataStorePlayer.playerUnityPosition.Set(characterPosition.unityPosition);
 218
 6093219        if (Moved(lastPosition))
 220        {
 5380221            if (Moved(lastPosition, useThreshold: true))
 5380222                ReportMovement();
 223
 5380224            OnCharacterMoved?.Invoke(characterPosition);
 225
 5380226            float distance = Vector3.Distance(characterPosition.worldPosition, lastPosition) - movingPlatformSpeed;
 227
 5380228            if (distance > 0f && isGrounded)
 6229                OnMoved?.Invoke(distance);
 230        }
 231
 6093232        lastPosition = transform.position;
 6093233    }
 234
 235    public void Teleport(string teleportPayload)
 236    {
 40237        var payload = Utils.FromJsonWithNulls<Vector3>(teleportPayload);
 40238        dataStorePlayer.lastTeleportPosition.Set(payload, notifyEvent: true);
 40239    }
 240
 241    private void Teleport(Vector3 newPosition, Vector3 prevPosition)
 242    {
 41243        ResetGround();
 244
 41245        SetPosition(newPosition);
 246
 41247        if (OnPositionSet != null)
 248        {
 0249            OnPositionSet.Invoke(characterPosition);
 250        }
 251
 41252        if (!initialPositionAlreadySet)
 253        {
 37254            initialPositionAlreadySet = true;
 255        }
 41256    }
 257
 258    [Obsolete("SetPosition is deprecated, please use Teleport instead.", true)]
 0259    public void SetPosition(string positionVector) { Teleport(positionVector); }
 260
 1206261    public void SetEnabled(bool enabled) { this.enabled = enabled; }
 262
 263    bool Moved(Vector3 previousPosition, bool useThreshold = false)
 264    {
 11473265        if (useThreshold)
 5380266            return Vector3.Distance(characterPosition.worldPosition, previousPosition) > 0.001f;
 267        else
 6093268            return characterPosition.worldPosition != previousPosition;
 269    }
 270
 271    internal void LateUpdate()
 272    {
 6051273        if(!dataStorePlayer.canPlayerMove.Get())
 0274            return;
 275
 6051276        if (transform.position.y < minimumYPosition)
 277        {
 0278            SetPosition(characterPosition.worldPosition);
 0279            return;
 280        }
 281
 6051282        if (freeMovementController.IsActive())
 283        {
 0284            velocity = freeMovementController.CalculateMovement();
 285        }
 286        else
 287        {
 6051288            velocity.x = 0f;
 6051289            velocity.z = 0f;
 6051290            velocity.y += gravity * Time.deltaTime;
 291
 6051292            bool previouslyGrounded = isGrounded;
 293
 6051294            if (!isJumping || velocity.y <= 0f)
 6051295                CheckGround();
 296
 6051297            if (isGrounded)
 298            {
 340299                isJumping = false;
 340300                velocity.y = gravity * Time.deltaTime; // to avoid accumulating gravity in velocity.y while grounded
 301            }
 5711302            else if (previouslyGrounded && !isJumping)
 303            {
 10304                lastUngroundedTime = Time.time;
 305            }
 306
 6051307            if (characterForward.HasValue())
 308            {
 309                // Horizontal movement
 34310                var speed = movementSpeed * (isWalking ? runningSpeedMultiplier : 1f);
 311
 34312                transform.forward = characterForward.Get().Value;
 313
 34314                var xzPlaneForward = Vector3.Scale(cameraForward.Get(), new Vector3(1, 0, 1));
 34315                var xzPlaneRight = Vector3.Scale(cameraRight.Get(), new Vector3(1, 0, 1));
 316
 34317                Vector3 forwardTarget = Vector3.zero;
 318
 34319                if (characterYAxis.GetValue() > CONTROLLER_DRIFT_OFFSET)
 0320                    forwardTarget += xzPlaneForward;
 34321                if (characterYAxis.GetValue() < -CONTROLLER_DRIFT_OFFSET)
 0322                    forwardTarget -= xzPlaneForward;
 323
 34324                if (characterXAxis.GetValue() > CONTROLLER_DRIFT_OFFSET)
 0325                    forwardTarget += xzPlaneRight;
 34326                if (characterXAxis.GetValue() < -CONTROLLER_DRIFT_OFFSET)
 0327                    forwardTarget -= xzPlaneRight;
 328
 34329                if (forwardTarget.Equals(Vector3.zero))
 34330                    isMovingByUserInput = false;
 331                else
 0332                    isMovingByUserInput = true;
 333
 334
 34335                forwardTarget.Normalize();
 34336                velocity += forwardTarget * speed;
 34337                CommonScriptableObjects.playerUnityEulerAngles.Set(transform.eulerAngles);
 338            }
 339
 6051340            bool jumpButtonPressedWithGraceTime = jumpButtonPressed && (Time.time - lastJumpButtonPressedTime < 0.15f);
 341
 6051342            if (jumpButtonPressedWithGraceTime) // almost-grounded jump button press allowed time
 343            {
 0344                bool justLeftGround = (Time.time - lastUngroundedTime) < 0.1f;
 345
 0346                if (isGrounded || justLeftGround) // just-left-ground jump allowed time
 347                {
 0348                    Jump();
 349                }
 350            }
 351
 352            //NOTE(Mordi): Detecting when the character hits the ground (for landing-SFX)
 6051353            if (isGrounded && !previouslyGrounded && (Time.time - lastUngroundedTime) > 0.4f)
 354            {
 22355                OnHitGround?.Invoke();
 356            }
 357        }
 358
 6051359        if (characterController.enabled)
 360        {
 361            //NOTE(Brian): Transform has to be in sync before the Move call, otherwise this call
 362            //             will reset the character controller to its previous position.
 6051363            Environment.i.platform.physicsSyncController?.Sync();
 6051364            lastCharacterControllerCollision = characterController.Move(velocity * Time.deltaTime);
 365        }
 366
 6051367        SetPosition(PositionUtils.UnityToWorldPosition(transform.position));
 368
 6051369        if ((DCLTime.realtimeSinceStartup - lastMovementReportTime) > PlayerSettings.POSITION_REPORTING_DELAY)
 370        {
 72371            ReportMovement();
 372        }
 373
 6051374        if (isOnMovingPlatform)
 375        {
 0376            SaveLateUpdateGroundTransforms();
 377        }
 6051378        OnUpdateFinish?.Invoke(Time.deltaTime);
 0379    }
 380
 381    private void SaveLateUpdateGroundTransforms()
 382    {
 0383        lastLocalGroundPosition = groundTransform.InverseTransformPoint(transform.position);
 384
 0385        if (CommonScriptableObjects.characterForward.HasValue())
 386        {
 0387            lastCharacterRotation = groundTransform.InverseTransformDirection(CommonScriptableObjects.characterForward.G
 0388            lastGlobalCharacterRotation = CommonScriptableObjects.characterForward.Get().Value;
 389        }
 0390    }
 391
 392    void Jump()
 393    {
 0394        if (isJumping)
 0395            return;
 396
 0397        isJumping = true;
 0398        isGrounded = false;
 399
 0400        ResetGround();
 401
 0402        velocity.y = jumpForce;
 403        //cameraTargetProbe.damping.y = dampingOnAir;
 404
 0405        OnJump?.Invoke();
 0406    }
 407
 408    public void ResetGround()
 409    {
 11482410        if (isOnMovingPlatform)
 0411            CommonScriptableObjects.playerIsOnMovingPlatform.Set(false);
 412
 11482413        isOnMovingPlatform = false;
 11482414        groundTransform = null;
 11482415        movingPlatformSpeed = 0;
 11482416    }
 417
 418    void CheckGround()
 419    {
 6051420        if (groundTransform == null)
 5728421            ResetGround();
 422
 6051423        if (isOnMovingPlatform)
 424        {
 0425            Physics.SyncTransforms();
 426            //NOTE(Brian): This should move the character with the moving platform
 0427            Vector3 newGroundWorldPos = groundTransform.TransformPoint(lastLocalGroundPosition);
 0428            movingPlatformSpeed = Vector3.Distance(newGroundWorldPos, transform.position);
 0429            transform.position = newGroundWorldPos;
 430
 0431            Vector3 newCharacterForward = groundTransform.TransformDirection(lastCharacterRotation);
 0432            Vector3 lastFrameDifference = Vector3.zero;
 0433            if (CommonScriptableObjects.characterForward.HasValue())
 434            {
 0435                lastFrameDifference = CommonScriptableObjects.characterForward.Get().Value - lastGlobalCharacterRotation
 436            }
 437
 438            //NOTE(Kinerius) CameraStateTPS rotates the character between frames so we add the difference.
 439            //               if we dont do this, the character wont rotate when moving, only when the platform rotates
 0440            var newForward = newCharacterForward + lastFrameDifference;
 441
 0442            if (newForward is { x: 0, y: 0, z: 0 })
 0443                newForward = Vector3.forward;
 444
 0445            CommonScriptableObjects.characterForward.Set(newForward);
 446        }
 447
 6051448        Transform transformHit = CastGroundCheckingRays();
 449
 6051450        if (transformHit != null)
 451        {
 338452            if (groundTransform == transformHit)
 453            {
 315454                bool groundHasMoved = (transformHit.position != groundLastPosition || transformHit.rotation != groundLas
 455
 315456                if (!characterPosition.RepositionedWorldLastFrame()
 457                    && groundHasMoved)
 458                {
 0459                    isOnMovingPlatform = true;
 0460                    CommonScriptableObjects.playerIsOnMovingPlatform.Set(true);
 0461                    Physics.SyncTransforms();
 0462                    SaveLateUpdateGroundTransforms();
 463
 0464                    Quaternion deltaRotation = groundTransform.rotation * Quaternion.Inverse(groundLastRotation);
 0465                    CommonScriptableObjects.movingPlatformRotationDelta.Set(deltaRotation);
 466                }
 467            }
 468            else
 469            {
 23470                groundTransform = transformHit;
 23471                CommonScriptableObjects.movingPlatformRotationDelta.Set(Quaternion.identity);
 472            }
 473        }
 474        else
 475        {
 5713476            ResetGround();
 477        }
 478
 6051479        if (groundTransform != null)
 480        {
 338481            groundLastPosition = groundTransform.position;
 338482            groundLastRotation = groundTransform.rotation;
 483        }
 484
 6051485        isGrounded = IsLastCollisionGround() || groundTransform != null && groundTransform.gameObject.activeInHierarchy;
 6051486    }
 487
 488    public Transform CastGroundCheckingRays()
 489    {
 490        RaycastHit hitInfo;
 491
 6051492        var result = CastGroundCheckingRays(transform, collider, groundCheckExtraDistance, 0.9f, groundLayers, out hitIn
 493
 6051494        if ( result )
 495        {
 338496            return hitInfo.transform;
 497        }
 498
 5713499        return null;
 500    }
 501
 502    public bool CastGroundCheckingRays(float extraDistance, float scale, out RaycastHit hitInfo)
 503    {
 6005504        if (CastGroundCheckingRays(transform, collider, extraDistance, scale, groundLayers | cameraLayers , out hitInfo)
 425505            return true;
 506
 5580507        return IsLastCollisionGround();
 508    }
 509
 510    public bool CastGroundCheckingRay(float extraDistance, out RaycastHit hitInfo)
 511    {
 0512        Bounds bounds = collider.bounds;
 0513        float rayMagnitude = (bounds.extents.y + extraDistance);
 0514        bool test = CastGroundCheckingRay(transform.position, out hitInfo, rayMagnitude, groundLayers);
 0515        return IsLastCollisionGround() || test;
 516    }
 517
 518    // We secuentially cast rays in 4 directions (only if the previous one didn't hit anything)
 519    public static bool CastGroundCheckingRays(Transform transform, Collider collider, float extraDistance, float scale, 
 520    {
 12056521        Bounds bounds = collider.bounds;
 522
 12056523        float rayMagnitude = (bounds.extents.y + extraDistance);
 12056524        float originScale = scale * bounds.extents.x;
 525
 12056526        if (!CastGroundCheckingRay(transform.position, out hitInfo, rayMagnitude, groundLayers) // center
 527            && !CastGroundCheckingRay( transform.position + transform.forward * originScale, out hitInfo, rayMagnitude, 
 528            && !CastGroundCheckingRay( transform.position + transform.right * originScale, out hitInfo, rayMagnitude, gr
 529            && !CastGroundCheckingRay( transform.position + -transform.forward * originScale, out hitInfo, rayMagnitude,
 530            && !CastGroundCheckingRay( transform.position + -transform.right * originScale, out hitInfo, rayMagnitude, g
 531        {
 11293532            return false;
 533        }
 534
 535        // At this point there is a guaranteed hit, so this is not null
 763536        return true;
 537    }
 538
 539    public static bool CastGroundCheckingRay(Vector3 origin, out RaycastHit hitInfo, float rayMagnitude, int groundLayer
 540    {
 57228541        var ray = new Ray();
 57228542        ray.origin = origin;
 57228543        ray.direction = Vector3.down * rayMagnitude;
 544
 57228545        var result = Physics.Raycast(ray, out hitInfo, rayMagnitude, groundLayers);
 546
 547#if UNITY_EDITOR
 57228548        if ( result )
 763549            Debug.DrawLine(ray.origin, hitInfo.point, Color.green);
 550        else
 56465551            Debug.DrawRay(ray.origin, ray.direction, Color.red);
 552#endif
 553
 56465554        return result;
 555    }
 556
 557    public void ReportMovement()
 558    {
 5452559        var reportPosition = characterPosition.worldPosition;
 5452560        var compositeRotation = Quaternion.LookRotation(characterForward.HasValue() ? characterForward.Get().Value : cam
 5452561        var cameraRotation = Quaternion.LookRotation(cameraForward.Get());
 562
 563        //NOTE(Brian): We have to wait for a Teleport before sending the ReportPosition, because if not ReportPosition e
 564        //             When the spawn point is being selected / scenes being prepared to be sent and the Kernel gets cra
 565
 566        //             The race conditions that can arise from not having this flag can result in:
 567        //                  - Scenes not being sent for loading, making ActivateRenderer never being sent, only in WSS m
 568        //                  - Random teleports to 0,0 or other positions that shouldn't happen.
 5452569        if (initialPositionAlreadySet)
 77570            WebInterface.ReportPosition(reportPosition, compositeRotation, characterController.height, cameraRotation);
 571
 5452572        lastMovementReportTime = DCLTime.realtimeSinceStartup;
 5452573    }
 574
 575    public void PauseGravity()
 576    {
 40577        gravity = 0f;
 40578        velocity.y = 0f;
 40579    }
 580
 0581    public void ResumeGravity() { gravity = originalGravity; }
 582
 583    void OnRenderingStateChanged(bool isEnable, bool prevState)
 584    {
 603585        SetEnabled(isEnable && !DataStore.i.common.isSignUpFlow.Get());
 603586    }
 587
 588    bool IsLastCollisionGround()
 589    {
 11631590        return (lastCharacterControllerCollision & CollisionFlags.Below) != 0;
 591    }
 592}