< Summary

Class:PlayerName
Assembly:PlayerName
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/PlayerName/PlayerName.cs
Covered lines:70
Uncovered lines:17
Coverable lines:87
Total lines:195
Line coverage:80.4% (70 of 87)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
PlayerName()0%110100%
PlayerName()0%110100%
Awake()0%110100%
OnNamesOpacityChanged(...)0%110100%
OnNamesVisibleChanged(...)0%330100%
SetName(...)0%110100%
AsyncSetName()0%3.333066.67%
Update()0%110100%
SetRenderersVisible(...)0%110100%
Update(...)0%7.057090%
LookAtCamera(...)0%110100%
Show(...)0%220100%
Hide(...)0%330100%
AddVisibilityConstaint(...)0%2100%
RemoveVisibilityConstaint(...)0%2100%
SetForceShow(...)0%42600%
SetIsTalking(...)0%110100%
SetYOffset(...)0%110100%
ScreenSpaceRect(...)0%2100%
ScreenSpacePos(...)0%110100%
ResolveAlphaByDistance(...)0%3.583060%
UpdateVisuals(...)0%110100%
ScalePivotByDistance(...)0%110100%
GetPivotYOffsetByDistance(...)0%2.152066.67%
OnDestroy()0%110100%

File(s)

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

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using Cysharp.Threading.Tasks;
 4using DCL;
 5using TMPro;
 6using UnityEngine;
 7using UnityEngine.UI;
 8
 9[Serializable]
 10public class PlayerName : MonoBehaviour, IPlayerName
 11{
 12    internal const int DEFAULT_CANVAS_SORTING_ORDER = 0;
 13    internal const int FORCE_CANVAS_SORTING_ORDER = 40;
 114    internal static readonly int TALKING_ANIMATOR_BOOL = Animator.StringToHash("Talking");
 15    internal const float ALPHA_TRANSITION_STEP_PER_SECOND =  1f / 0.25f;
 16    internal const float TARGET_ALPHA_SHOW = 1;
 17    internal const float TARGET_ALPHA_HIDE = 0;
 18    internal const int BACKGROUND_HEIGHT = 30;
 19    internal const int BACKGROUND_EXTRA_WIDTH = 10;
 20
 21    [SerializeField] internal Canvas canvas;
 22    [SerializeField] internal CanvasGroup canvasGroup;
 23    [SerializeField] internal TextMeshProUGUI nameText;
 24    [SerializeField] internal Image background;
 25    [SerializeField] internal Transform pivot;
 26    [SerializeField] internal Animator talkingAnimator;
 27
 28    [SerializeField] internal List<CanvasRenderer> canvasRenderers;
 29
 133830    internal BaseVariable<float> namesOpacity => DataStore.i.HUDs.avatarNamesOpacity;
 133831    internal BaseVariable<bool> namesVisible => DataStore.i.HUDs.avatarNamesVisible;
 32
 33    internal float alpha;
 34    internal float targetAlpha;
 35    internal bool forceShow = false;
 36    internal Color backgroundOriginalColor;
 45237    internal List<string> hideConstraints = new List<string>();
 38
 39    private void Awake()
 40    {
 44641        backgroundOriginalColor = background.color;
 44642        canvas.sortingOrder = DEFAULT_CANVAS_SORTING_ORDER;
 44643        namesVisible.OnChange += OnNamesVisibleChanged;
 44644        namesOpacity.OnChange += OnNamesOpacityChanged;
 44645        OnNamesVisibleChanged(namesVisible.Get(), true);
 44646        OnNamesOpacityChanged(namesOpacity.Get(), 1);
 44647        Show(true);
 44648    }
 90449    internal void OnNamesOpacityChanged(float current, float previous) { background.color = new Color(backgroundOriginal
 50
 89651    internal void OnNamesVisibleChanged(bool current, bool previous) { canvas.enabled = current || forceShow; }
 52
 2653    public void SetName(string name) { AsyncSetName(name).Forget(); }
 54    private async UniTaskVoid AsyncSetName(string name)
 55    {
 1356        name = await ProfanityFilterSharedInstances.regexFilter.Filter(name);
 1357        nameText.text = name;
 1358        background.rectTransform.sizeDelta = new Vector2(nameText.GetPreferredValues().x + BACKGROUND_EXTRA_WIDTH, BACKG
 1359    }
 60
 9461    private void Update() { Update(Time.deltaTime); }
 62
 63    private void SetRenderersVisible(bool value)
 64    {
 338165        canvasRenderers.ForEach(c => c.SetAlpha(value ? 1f : 0f));
 48366    }
 67
 68    internal void Update(float deltaTime)
 69    {
 5070        if (hideConstraints.Count > 0)
 71        {
 072            UpdateVisuals(0);
 073            return;
 74        }
 75
 5076        float finalTargetAlpha = forceShow ? TARGET_ALPHA_SHOW : targetAlpha;
 77
 5078        if (!Mathf.Approximately(alpha, finalTargetAlpha))
 2079            alpha = Mathf.MoveTowards(alpha, finalTargetAlpha, ALPHA_TRANSITION_STEP_PER_SECOND * deltaTime);
 3080        else if (alpha == 0)
 81        {
 282            UpdateVisuals(0);
 83            // We are hidden and we dont have to scale, look at camera or anything, we can disable the gameObject
 284            SetRenderersVisible(false);
 285            return;
 86        }
 4887        Vector3 cameraPosition = CommonScriptableObjects.cameraPosition.Get();
 4888        Vector3 cameraRight = CommonScriptableObjects.cameraRight.Get();
 4889        Quaternion cameraRotation = DataStore.i.camera.rotation.Get();
 90
 91        /*
 92         * TODO: We could obtain distance to player from the AvatarLODController but that coupling it's overkill and ugl
 93         * instead we should have a provider so all the subsystems can use it
 94         */
 4895        float distanceToCamera = Vector3.Distance(cameraPosition, gameObject.transform.position);
 4896        float resolvedAlpha = forceShow ? TARGET_ALPHA_SHOW : ResolveAlphaByDistance(alpha, distanceToCamera, forceShow)
 4897        UpdateVisuals(resolvedAlpha);
 4898        ScalePivotByDistance(distanceToCamera);
 4899        LookAtCamera(cameraRight, cameraRotation.eulerAngles);
 48100        pivot.transform.localPosition = Vector3.up * GetPivotYOffsetByDistance(distanceToCamera);
 48101    }
 102
 103    internal void LookAtCamera(Vector3 cameraRight, Vector3 cameraEulerAngles)
 104    {
 49105        Transform cachedTransform = transform;
 49106        cachedTransform.right = -cameraRight; // This will set the Y rotation
 107
 108        // Now we use the negated X axis rotation to make the rotation steady in horizont
 49109        Vector3 finalEulerAngle = cachedTransform.localEulerAngles;
 49110        finalEulerAngle.x = -cameraEulerAngles.x;
 49111        cachedTransform.localEulerAngles = finalEulerAngle;
 49112    }
 113
 114    public void Show(bool instant = false)
 115    {
 466116        targetAlpha = TARGET_ALPHA_SHOW;
 466117        SetRenderersVisible(true);
 466118        if (instant)
 450119            alpha = TARGET_ALPHA_SHOW;
 466120    }
 121
 122    public void Hide(bool instant = false)
 123    {
 30124        targetAlpha = TARGET_ALPHA_HIDE;
 30125        if (instant && !forceShow)
 126        {
 15127            alpha = TARGET_ALPHA_HIDE;
 15128            SetRenderersVisible(false);
 129        }
 30130    }
 131
 132    // Note: Ideally we should separate the LODController logic from this one so we don't have to add constraints
 0133    public void AddVisibilityConstaint(string constraint) { hideConstraints.Add(constraint); }
 134
 0135    public void RemoveVisibilityConstaint(string constraint) { hideConstraints.Remove(constraint); }
 136
 137    public void SetForceShow(bool forceShow)
 138    {
 0139        canvas.enabled = forceShow || namesVisible.Get();
 0140        canvas.sortingOrder = forceShow ? FORCE_CANVAS_SORTING_ORDER : DEFAULT_CANVAS_SORTING_ORDER;
 0141        background.color = new Color(backgroundOriginalColor.r, backgroundOriginalColor.g, backgroundOriginalColor.b, fo
 0142        this.forceShow = forceShow;
 0143        if (this.forceShow)
 0144            SetRenderersVisible(true);
 0145    }
 146
 10147    public void SetIsTalking(bool talking) { talkingAnimator.SetBool(TALKING_ANIMATOR_BOOL, talking); }
 148
 10149    public void SetYOffset(float yOffset) { transform.localPosition = Vector3.up * yOffset; }
 150
 151    public Rect ScreenSpaceRect(Camera mainCamera)
 152    {
 0153        Vector3 origin = mainCamera.WorldToScreenPoint(background.transform.position);
 0154        Vector2 size = background.rectTransform.sizeDelta;
 0155        return new Rect(origin.x, Screen.height - origin.y, size.x, size.y);
 156    }
 157
 24158    public Vector3 ScreenSpacePos(Camera mainCamera) { return mainCamera.WorldToScreenPoint(background.transform.positio
 159
 160    internal static float ResolveAlphaByDistance(float alphaValue, float distanceToCamera, bool forceShow)
 161    {
 48162        if (forceShow)
 0163            return alphaValue;
 164
 165        const float MIN_DISTANCE = 5;
 48166        if (distanceToCamera < MIN_DISTANCE)
 48167            return alphaValue;
 168
 0169        return alphaValue * Mathf.Lerp(1, 0, (distanceToCamera - MIN_DISTANCE) / (DataStore.i.avatarsLOD.LODDistance.Get
 170    }
 171
 172    internal void UpdateVisuals(float resolvedAlpha)
 173    {
 50174        canvasGroup.alpha = resolvedAlpha;
 50175    }
 176
 96177    internal void ScalePivotByDistance(float distanceToCamera) { pivot.transform.localScale = Vector3.one * 0.15f * dist
 178
 179    internal float GetPivotYOffsetByDistance(float distanceToCamera)
 180    {
 181        const float NEAR_Y_OFFSET = 0f;
 182        const float FAR_Y_OFFSET = 0.1f;
 183        const float MAX_DISTANCE = 5;
 48184        if (distanceToCamera >= MAX_DISTANCE)
 0185            return FAR_Y_OFFSET;
 186
 48187        return Mathf.Lerp(NEAR_Y_OFFSET, FAR_Y_OFFSET, distanceToCamera / MAX_DISTANCE);
 188    }
 189
 190    private void OnDestroy()
 191    {
 446192        namesVisible.OnChange -= OnNamesVisibleChanged;
 446193        namesOpacity.OnChange -= OnNamesOpacityChanged;
 446194    }
 195}