< Summary

Class:DCL.AvatarMovementController
Assembly:AvatarShape
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/AvatarMovementController.cs
Covered lines:31
Uncovered lines:44
Coverable lines:75
Total lines:199
Line coverage:41.3% (31 of 75)
Covered branches:0
Total branches:0
Covered methods:14
Total methods:21
Method coverage:66.6% (14 of 21)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
AvatarMovementController()0%110100%
OnPoolGet()0%110100%
OnPoolRelease()0%110100%
SetAvatarTransform(...)0%110100%
OnEnable()0%110100%
OnDisable()0%110100%
OnWorldReposition(...)0%2100%
OnTransformChanged(...)0%2100%
OnTransformChanged(...)0%2100%
MoveTo(...)0%20400%
UpdateLerp(...)0%2.262060%
UpdateRotation(...)0%110100%
UpdateMovement(...)0%12300%
Update()0%220100%
SetMovementLerpWait(...)0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/AvatarMovementController.cs

#LineLine coverage
 1using AvatarSystem;
 2using DCL.Components;
 3using DCL.Helpers;
 4using System;
 5using UnityEngine;
 6
 7namespace DCL
 8{
 9    public class AvatarMovementController : MonoBehaviour, IPoolLifecycleHandler, IAvatarMovementController
 10    {
 11        // Speed values are slightly slower than the player
 12        private const float WALK_SPEED = 4f;
 13        private const float RUN_SPEED = 10.0f;
 14
 15        private const float SPEED_GRAVITY = 11.0f;
 16        private const float ROTATION_SPEED = 6.25f;
 17        private const float SPEED_EPSILON = 0.0001f;
 18        private const float WALK_DISTANCE = 1.5f;
 31419        private float movementSpeed = WALK_SPEED;
 20
 21        private Transform avatarTransformValue;
 22
 23        private Quaternion targetRotation;
 31424        private Vector3 currentWorldPosition = Vector3.zero;
 25        private Vector3 targetPosition;
 26
 27        private float movementLerpWait = 0f;
 28        private float movementLerpWaitCounter = 0f;
 29
 30
 31        private Transform AvatarTransform
 32        {
 33            get
 34            {
 235                if (avatarTransformValue == null)
 36                {
 137                    avatarTransformValue = GetComponent<AvatarShape>().entity.gameObject.transform;
 138                    enabled = true;
 39                }
 40
 241                return avatarTransformValue;
 42            }
 43            set
 44            {
 345                avatarTransformValue = value;
 46
 347                if (value == null)
 148                    enabled = false;
 349            }
 50        }
 51
 52        private Vector3 CurrentPosition
 53        {
 154            get { return currentWorldPosition; }
 55            set
 56            {
 057                currentWorldPosition = value;
 058                Vector3 newPosition = PositionUtils.WorldToUnityPosition(currentWorldPosition);
 059                if (float.IsNaN(newPosition.x) || float.IsInfinity(newPosition.x) ||
 60                    float.IsNaN(newPosition.z) || float.IsInfinity(newPosition.z) ||
 61                    float.IsNaN(newPosition.y) || float.IsInfinity(newPosition.y))
 062                    return;
 63
 064                AvatarTransform.position = newPosition;
 065            }
 66        }
 67
 68        private Quaternion CurrentRotation
 69        {
 170            get { return AvatarTransform.rotation; }
 271            set { AvatarTransform.rotation = value; }
 72        }
 73
 174        public void OnPoolGet() { }
 75
 76        public void OnPoolRelease()
 77        {
 178            AvatarTransform = null;
 79
 180            currentWorldPosition = Vector3.zero;
 181        }
 82
 83        public void SetAvatarTransform(Transform avatarTransform)
 84        {
 285            AvatarTransform = avatarTransform;
 286        }
 87
 62288        private void OnEnable() { CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition; }
 89
 62290        private void OnDisable() { CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition; }
 91
 92        private void OnWorldReposition(Vector3 current, Vector3 previous)
 93        {
 094            AvatarTransform.position = PositionUtils.WorldToUnityPosition(currentWorldPosition);
 095        }
 96
 97        public void OnTransformChanged(Vector3 newPosition, Quaternion newRotation)
 98        {
 099            OnTransformChanged(newPosition, newRotation, false);
 0100        }
 101
 102        public void OnTransformChanged(Vector3 position, Quaternion rotation, bool immediate)
 103        {
 0104            float characterMinHeight = DCLCharacterController.i.characterController.height * 0.5f;
 105
 0106            MoveTo(
 107                new Vector3(position.x, Math.Max(position.y - characterMinHeight, -characterMinHeight), position.z), // 
 108                rotation,
 109                immediate);
 0110        }
 111
 112        public void MoveTo(Vector3 position, Quaternion rotation, bool immediate = false)
 113        {
 0114            if (immediate)
 115            {
 0116                CurrentPosition = position;
 0117                AvatarTransform.rotation = rotation;
 118            }
 119
 0120            Vector3 flatEulerRotation = rotation.eulerAngles;
 0121            flatEulerRotation.z = flatEulerRotation.x = 0;
 0122            rotation = Quaternion.Euler(flatEulerRotation);
 123
 0124            targetPosition = position;
 0125            targetRotation = rotation;
 126
 0127            float distance = Vector3.Distance(targetPosition, CurrentPosition);
 128
 0129            if (distance >= 50)
 130            {
 0131                CurrentPosition = position;
 0132                AvatarTransform.rotation = rotation;
 133            }
 134
 0135            if (distance >= WALK_DISTANCE)
 0136                movementSpeed = Mathf.MoveTowards(movementSpeed, RUN_SPEED, Time.deltaTime * RUN_SPEED * 10);
 137            else
 0138                movementSpeed = Mathf.MoveTowards(movementSpeed, WALK_SPEED, Time.deltaTime * RUN_SPEED * 30);
 0139        }
 140
 141        void UpdateLerp(float deltaTime)
 142        {
 1143            if (Vector3.SqrMagnitude(CurrentPosition - targetPosition) < SPEED_EPSILON)
 144            {
 1145                UpdateRotation(deltaTime, targetRotation);
 1146                return;
 147            }
 148
 149            //NOTE(Brian): When we update movement we don't update rotation, because the Avatar will face the movement f
 0150            UpdateMovement(deltaTime);
 0151        }
 152
 153        private void UpdateRotation(float deltaTime, Quaternion targetRotation)
 154        {
 1155            CurrentRotation = Quaternion.Slerp(CurrentRotation, targetRotation, ROTATION_SPEED * deltaTime);
 1156        }
 157
 158        private void UpdateMovement(float deltaTime)
 159        {
 0160            Vector3 flattenedDiff = targetPosition - CurrentPosition;
 0161            flattenedDiff.y = 0;
 162
 163            //NOTE(Brian): Avoid Unity error when computing look rotation for 0 magnitude vectors.
 164            //             Note that this isn't the same as the previous distance check because this
 165            //             is computed with a flattened vector.
 0166            if (flattenedDiff != Vector3.zero)
 167            {
 0168                Quaternion lookRotation = Quaternion.LookRotation(flattenedDiff, Vector3.up);
 0169                UpdateRotation(deltaTime, lookRotation);
 170            }
 171
 0172            Vector3 direction = (targetPosition - CurrentPosition).normalized;
 0173            Vector3 delta = direction * (movementSpeed * deltaTime);
 174
 175            //NOTE(Brian): We need a separate value for Y movement because the gravity has to be lerped faster.
 0176            delta.y = direction.y * SPEED_GRAVITY * deltaTime;
 177
 178            //NOTE(Brian): If we overshoot targetPosition we adjust the delta value accordingly.
 0179            if (delta.sqrMagnitude > Vector3.SqrMagnitude(targetPosition - CurrentPosition))
 180            {
 0181                delta = targetPosition - CurrentPosition;
 182            }
 183
 0184            CurrentPosition += delta;
 0185        }
 186
 187        private void Update()
 188        {
 1189            movementLerpWaitCounter += Time.deltaTime;
 1190            if (movementLerpWaitCounter >= movementLerpWait)
 191            {
 1192                UpdateLerp(movementLerpWaitCounter);
 1193                movementLerpWaitCounter = 0f;
 194            }
 1195        }
 196
 0197        public void SetMovementLerpWait(float secondsBetweenUpdates) { movementLerpWait = secondsBetweenUpdates; }
 198    }
 199}