< Summary

Class:DCL.AvatarShape
Assembly:AvatarShape
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/AvatarShape.cs
Covered lines:56
Uncovered lines:72
Coverable lines:128
Total lines:273
Line coverage:43.7% (56 of 128)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
AvatarShape()0%110100%
Awake()0%220100%
Start()0%220100%
PlayerClicked()0%6200%
OnDestroy()0%330100%
ApplyChanges()0%28.089038.24%
PlayerPointerExit()0%6200%
PlayerPointerEnter()0%6200%
UpdatePlayerStatus(...)0%90900%
Update()0%2.862040%
DisablePassport()0%2.062075%
EnablePassport()0%6200%
OnEntityTransformChanged(...)0%2100%
OnPoolGet()0%110100%
OnImpostorAlphaValueUpdate(...)0%12300%
Cleanup()0%5.055087.5%
GetClassId()0%2100%

File(s)

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

#LineLine coverage
 1using System;
 2using DCL.Components;
 3using DCL.Interface;
 4using System.Collections;
 5using DCL.Configuration;
 6using DCL.Models;
 7using UnityEngine;
 8
 9namespace DCL
 10{
 11    public class AvatarShape : BaseComponent
 12    {
 13        private const string CURRENT_PLAYER_ID = "CurrentPlayerInfoCardId";
 14        private const float MINIMUM_PLAYERNAME_HEIGHT = 2.7f;
 15        private const float AVATAR_PASSPORT_TOGGLE_ALPHA_THRESHOLD = 0.9f;
 16
 17        public static event Action<IDCLEntity, AvatarShape> OnAvatarShapeUpdated;
 18
 19        public AvatarRenderer avatarRenderer;
 20        public Collider avatarCollider;
 21        public AvatarMovementController avatarMovementController;
 22
 23        [SerializeField] internal AvatarOnPointerDown onPointerDown;
 24        internal IPlayerName playerName;
 25        internal IAvatarReporterController avatarReporterController;
 26
 27        private StringVariable currentPlayerInfoCardId;
 28
 67129        private AvatarModel oldModel = new AvatarModel();
 30
 31        public bool everythingIsLoaded;
 32
 33        private Vector3? lastAvatarPosition = null;
 34        bool initializedPosition = false;
 35
 36        private Player player = null;
 037        private BaseDictionary<string, Player> otherPlayers => DataStore.i.player.otherPlayers;
 38
 67139        private IAvatarAnchorPoints anchorPoints = new AvatarAnchorPoints();
 40
 41        private void Awake()
 42        {
 67043            model = new AvatarModel();
 67044            currentPlayerInfoCardId = Resources.Load<StringVariable>(CURRENT_PLAYER_ID);
 67045            avatarRenderer.OnImpostorAlphaValueUpdate += OnImpostorAlphaValueUpdate;
 46
 67047            if (avatarReporterController == null)
 48            {
 67049                avatarReporterController = new AvatarReporterController(Environment.i.world.state);
 50            }
 67051        }
 52
 53        private void Start()
 54        {
 155            playerName = GetComponentInChildren<IPlayerName>();
 156            playerName?.Hide(true);
 157        }
 58
 59        private void PlayerClicked()
 60        {
 061            if (model == null)
 062                return;
 063            currentPlayerInfoCardId.Set(((AvatarModel) model).id);
 064        }
 65
 66        public void OnDestroy()
 67        {
 67068            Cleanup();
 69
 67070            if (poolableObject != null && poolableObject.isInsidePool)
 271                poolableObject.RemoveFromPool();
 72
 67073            avatarRenderer.OnImpostorAlphaValueUpdate -= OnImpostorAlphaValueUpdate;
 67074        }
 75
 76        public override IEnumerator ApplyChanges(BaseModel newModel)
 77        {
 278            DisablePassport();
 79
 280            var model = (AvatarModel) newModel;
 81#if UNITY_EDITOR
 282            gameObject.name = $"Avatar Shape {model.name}";
 83#endif
 284            everythingIsLoaded = false;
 85
 286            bool avatarDone = false;
 287            bool avatarFailed = false;
 88
 289            yield return null; //NOTE(Brian): just in case we have a Object.Destroy waiting to be resolved.
 90
 91            // To deal with the cases in which the entity transform was configured before the AvatarShape
 192            if (!initializedPosition && entity.components.ContainsKey(DCL.Models.CLASS_ID_COMPONENT.TRANSFORM))
 93            {
 194                initializedPosition = true;
 95
 196                float characterHeight = DCLCharacterController.i != null ? DCLCharacterController.i.characterController.
 97
 198                avatarMovementController.MoveTo(
 99                    entity.gameObject.transform.localPosition - Vector3.up * characterHeight / 2,
 100                    entity.gameObject.transform.localRotation, true);
 101            }
 102
 1103            avatarRenderer.ApplyModel(model, () => avatarDone = true, () => avatarFailed = true);
 104
 3105            yield return new WaitUntil(() => avatarDone || avatarFailed);
 106
 0107            entity.OnTransformChange -= avatarMovementController.OnTransformChanged;
 0108            entity.OnTransformChange += avatarMovementController.OnTransformChanged;
 109
 0110            entity.OnTransformChange -= OnEntityTransformChanged;
 0111            entity.OnTransformChange += OnEntityTransformChanged;
 112
 0113            onPointerDown.OnPointerDownReport -= PlayerClicked;
 0114            onPointerDown.OnPointerDownReport += PlayerClicked;
 0115            onPointerDown.OnPointerEnterReport -= PlayerPointerEnter;
 0116            onPointerDown.OnPointerEnterReport += PlayerPointerEnter;
 0117            onPointerDown.OnPointerExitReport -= PlayerPointerExit;
 0118            onPointerDown.OnPointerExitReport += PlayerPointerExit;
 119
 0120            UpdatePlayerStatus(model);
 121
 0122            onPointerDown.Initialize(
 123                new OnPointerDown.Model()
 124                {
 125                    type = OnPointerDown.NAME,
 126                    button = WebInterface.ACTION_BUTTON.POINTER.ToString(),
 127                    hoverText = "view profile"
 128                },
 129                entity, player
 130            );
 131
 0132            avatarCollider.gameObject.SetActive(true);
 133
 0134            everythingIsLoaded = true;
 0135            OnAvatarShapeUpdated?.Invoke(entity, this);
 136
 0137            EnablePassport();
 138
 0139            bool isAvatarGlobalScene = scene.sceneData.id == EnvironmentSettings.AVATAR_GLOBAL_SCENE_ID;
 0140            onPointerDown.SetColliderEnabled(isAvatarGlobalScene);
 0141            onPointerDown.SetOnClickReportEnabled(isAvatarGlobalScene);
 142
 0143            KernelConfig.i.EnsureConfigInitialized()
 144                .Then(config =>
 145                {
 0146                    if (config.features.enableAvatarLODs)
 0147                        avatarRenderer.InitializeImpostor();
 0148                });
 0149        }
 150
 0151        private void PlayerPointerExit() { playerName?.SetForceShow(false); }
 0152        private void PlayerPointerEnter() { playerName?.SetForceShow(true); }
 153
 154        private void UpdatePlayerStatus(AvatarModel model)
 155        {
 156            // Remove the player status if the userId changes
 0157            if (player != null && (player.id != model.id || player.name != model.name))
 0158                otherPlayers.Remove(player.id);
 159
 0160            if (string.IsNullOrEmpty(model?.id))
 0161                return;
 162
 0163            bool isNew = false;
 0164            if (player == null)
 165            {
 0166                player = new Player();
 0167                isNew = true;
 168            }
 169
 0170            player.id = model.id;
 0171            player.name = model.name;
 0172            player.isTalking = model.talking;
 0173            player.worldPosition = entity.gameObject.transform.position;
 0174            player.renderer = avatarRenderer;
 0175            player.onPointerDownCollider = onPointerDown;
 176
 0177            if (isNew)
 178            {
 0179                player.playerName = playerName;
 0180                player.playerName.SetName(player.name);
 0181                player.playerName.Show();
 0182                player.anchorPoints = anchorPoints;
 0183                otherPlayers.Add(player.id, player);
 0184                avatarReporterController.ReportAvatarRemoved();
 185            }
 186
 0187            avatarReporterController.SetUp(entity.scene.sceneData.id, entity.entityId, player.id);
 0188            anchorPoints.Prepare(avatarRenderer.transform, avatarRenderer.GetBones(), avatarRenderer.maxY);
 189
 0190            player.playerName.SetIsTalking(model.talking);
 0191            player.playerName.SetYOffset(Mathf.Max(MINIMUM_PLAYERNAME_HEIGHT, avatarRenderer.maxY));
 0192        }
 193
 194        private void Update()
 195        {
 2196            if (player != null)
 197            {
 0198                player.worldPosition = entity.gameObject.transform.position;
 0199                player.forwardDirection = entity.gameObject.transform.forward;
 0200                avatarReporterController.ReportAvatarPosition(player.worldPosition);
 201            }
 2202        }
 203
 204        public void DisablePassport()
 205        {
 2206            if (onPointerDown.collider == null)
 0207                return;
 208
 2209            onPointerDown.SetPassportEnabled(false);
 2210        }
 211
 212        public void EnablePassport()
 213        {
 0214            if (onPointerDown.collider == null)
 0215                return;
 216
 0217            onPointerDown.SetPassportEnabled(true);
 0218        }
 219
 220        private void OnEntityTransformChanged(object newModel)
 221        {
 0222            DCLTransform.Model newTransformModel = (DCLTransform.Model)newModel;
 0223            lastAvatarPosition = newTransformModel.position;
 0224        }
 225
 226        public override void OnPoolGet()
 227        {
 2228            base.OnPoolGet();
 229
 2230            everythingIsLoaded = false;
 2231            initializedPosition = false;
 2232            oldModel = new AvatarModel();
 2233            model = new AvatarModel();
 2234            lastAvatarPosition = null;
 2235            player = null;
 2236        }
 237
 0238        void OnImpostorAlphaValueUpdate(float newAlphaValue) { avatarMovementController.movementLerpWait = newAlphaValue
 239
 240        public override void Cleanup()
 241        {
 674242            base.Cleanup();
 243
 674244            playerName?.Hide(true);
 674245            if (player != null)
 246            {
 0247                otherPlayers.Remove(player.id);
 0248                player = null;
 249            }
 250
 674251            avatarRenderer.CleanupAvatar();
 252
 674253            if (poolableObject != null)
 254            {
 6255                poolableObject.OnRelease -= Cleanup;
 256            }
 257
 674258            onPointerDown.OnPointerDownReport -= PlayerClicked;
 674259            onPointerDown.OnPointerEnterReport -= PlayerPointerEnter;
 674260            onPointerDown.OnPointerExitReport -= PlayerPointerExit;
 261
 674262            if (entity != null)
 263            {
 2264                entity.OnTransformChange = null;
 2265                entity = null;
 266            }
 267
 674268            avatarReporterController.ReportAvatarRemoved();
 674269        }
 270
 0271        public override int GetClassId() { return (int) CLASS_ID_COMPONENT.AVATAR_SHAPE; }
 272    }
 273}