< 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:192
Line coverage:41.3% (31 of 75)
Covered branches:0
Total branches:0

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 UnityEngine;
 5
 6namespace DCL
 7{
 8    public class AvatarMovementController : MonoBehaviour, IPoolLifecycleHandler, IAvatarMovementController
 9    {
 10        private const float SPEED_SLOW = 2.0f;
 11        private const float SPEED_FAST = 4.0f;
 12        private const float SPEED_ULTRA_FAST = 8.0f;
 13        private const float SPEED_GRAVITY = 8.0f;
 14        private const float ROTATION_SPEED = 6.25f;
 15        private const float SPEED_EPSILON = 0.0001f;
 33916        private float movementSpeed = SPEED_SLOW;
 17
 18        private Transform avatarTransformValue;
 19
 20        private Quaternion targetRotation;
 33921        private Vector3 currentWorldPosition = Vector3.zero;
 22        private Vector3 targetPosition;
 23
 24        private float movementLerpWait = 0f;
 25        private float movementLerpWaitCounter = 0f;
 26
 27
 28        private Transform AvatarTransform
 29        {
 30            get
 31            {
 232                if (avatarTransformValue == null)
 33                {
 134                    avatarTransformValue = GetComponent<AvatarShape>().entity.gameObject.transform;
 135                    enabled = true;
 36                }
 37
 238                return avatarTransformValue;
 39            }
 40            set
 41            {
 1342                avatarTransformValue = value;
 43
 1344                if (value == null)
 545                    enabled = false;
 1346            }
 47        }
 48
 49        private Vector3 CurrentPosition
 50        {
 151            get { return currentWorldPosition; }
 52            set
 53            {
 054                currentWorldPosition = value;
 055                Vector3 newPosition = PositionUtils.WorldToUnityPosition(currentWorldPosition);
 056                if (float.IsNaN(newPosition.x) || float.IsInfinity(newPosition.x) ||
 57                    float.IsNaN(newPosition.z) || float.IsInfinity(newPosition.z) ||
 58                    float.IsNaN(newPosition.y) || float.IsInfinity(newPosition.y))
 059                    return;
 60
 061                AvatarTransform.position = newPosition;
 062            }
 63        }
 64
 65        private Quaternion CurrentRotation
 66        {
 167            get { return AvatarTransform.rotation; }
 268            set { AvatarTransform.rotation = value; }
 69        }
 70
 571        public void OnPoolGet() { }
 72
 73        public void OnPoolRelease()
 74        {
 575            AvatarTransform = null;
 76
 577            currentWorldPosition = Vector3.zero;
 578        }
 79
 80        public void SetAvatarTransform(Transform avatarTransform)
 81        {
 882            AvatarTransform = avatarTransform;
 883        }
 84
 67685        private void OnEnable() { CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition; }
 86
 67687        private void OnDisable() { CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition; }
 88
 89        private void OnWorldReposition(Vector3 current, Vector3 previous)
 90        {
 091            AvatarTransform.position = PositionUtils.WorldToUnityPosition(currentWorldPosition);
 092        }
 93
 94        public void OnTransformChanged(object model)
 95        {
 096            DCLTransform.Model transformModel = (DCLTransform.Model)model;
 097            OnTransformChanged(transformModel.position, transformModel.rotation, false);
 098        }
 99
 100        public void OnTransformChanged(in Vector3 position, in Quaternion rotation, bool inmediate)
 101        {
 0102            var offsetPosition = new Vector3(0, DCLCharacterController.i.characterController.height * 0.5f, 0);
 0103            MoveTo(
 104                position - offsetPosition, // To fix the "always flying" avatars issue, We report the chara's centered p
 105                rotation,
 106                inmediate);
 0107        }
 108
 109        public void MoveTo(Vector3 position, Quaternion rotation, bool immediate = false)
 110        {
 0111            if (immediate)
 112            {
 0113                CurrentPosition = position;
 0114                AvatarTransform.rotation = rotation;
 115            }
 116
 0117            Vector3 flatEulerRotation = rotation.eulerAngles;
 0118            flatEulerRotation.z = flatEulerRotation.x = 0;
 0119            rotation = Quaternion.Euler(flatEulerRotation);
 120
 0121            targetPosition = position;
 0122            targetRotation = rotation;
 123
 0124            float distance = Vector3.Distance(targetPosition, currentWorldPosition);
 125
 0126            if (distance >= 50)
 0127                movementSpeed = float.MaxValue;
 0128            else if (distance >= 3)
 0129                movementSpeed = Mathf.Lerp(SPEED_SLOW, SPEED_ULTRA_FAST, (distance - 3) / 10.0f);
 130            else
 0131                movementSpeed = SPEED_SLOW;
 0132        }
 133
 134        void UpdateLerp(float deltaTime)
 135        {
 1136            if (Vector3.SqrMagnitude(CurrentPosition - targetPosition) < SPEED_EPSILON)
 137            {
 1138                UpdateRotation(deltaTime, targetRotation);
 1139                return;
 140            }
 141
 142            //NOTE(Brian): When we update movement we don't update rotation, because the Avatar will face the movement f
 0143            UpdateMovement(deltaTime);
 0144        }
 145
 146        private void UpdateRotation(float deltaTime, Quaternion targetRotation)
 147        {
 1148            CurrentRotation = Quaternion.Slerp(CurrentRotation, targetRotation, ROTATION_SPEED * deltaTime);
 1149        }
 150
 151        private void UpdateMovement(float deltaTime)
 152        {
 0153            Vector3 flattenedDiff = targetPosition - CurrentPosition;
 0154            flattenedDiff.y = 0;
 155
 156            //NOTE(Brian): Avoid Unity error when computing look rotation for 0 magnitude vectors.
 157            //             Note that this isn't the same as the previous distance check because this
 158            //             is computed with a flattened vector.
 0159            if (flattenedDiff != Vector3.zero)
 160            {
 0161                Quaternion lookRotation = Quaternion.LookRotation(flattenedDiff, Vector3.up);
 0162                UpdateRotation(deltaTime, lookRotation);
 163            }
 164
 0165            Vector3 direction = (targetPosition - CurrentPosition).normalized;
 0166            Vector3 delta = direction * (movementSpeed * deltaTime);
 167
 168            //NOTE(Brian): We need a separate value for Y movement because the gravity has to be lerped faster.
 0169            delta.y = direction.y * SPEED_GRAVITY * deltaTime;
 170
 171            //NOTE(Brian): If we overshoot targetPosition we adjust the delta value accordingly.
 0172            if (delta.sqrMagnitude > Vector3.SqrMagnitude(targetPosition - CurrentPosition))
 173            {
 0174                delta = targetPosition - CurrentPosition;
 175            }
 176
 0177            CurrentPosition += delta;
 0178        }
 179
 180        private void Update()
 181        {
 1182            movementLerpWaitCounter += Time.deltaTime;
 1183            if (movementLerpWaitCounter >= movementLerpWait)
 184            {
 1185                UpdateLerp(movementLerpWaitCounter);
 1186                movementLerpWaitCounter = 0f;
 187            }
 1188        }
 189
 0190        public void SetMovementLerpWait(float secondsBetweenUpdates) { movementLerpWait = secondsBetweenUpdates; }
 191    }
 192}