< Summary

Class:PlayerName
Assembly:PlayerName
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/PlayerName/PlayerName.cs
Covered lines:98
Uncovered lines:22
Coverable lines:120
Total lines:273
Line coverage:81.6% (98 of 120)
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%
OnProfanityFilterChanged(...)0%110100%
SetName(...)0%110100%
AsyncSetName()0%3.213071.43%
FilterName()0%64050%
IsProfanityFilteringEnabled()0%110100%
Update()0%110100%
SetRenderersVisible(...)0%220100%
Update(...)0%8.148086.96%
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%
GetNearestAlphaStep(...)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 MINIMUM_ALPHA_TO_SHOW =  1f / 32f;
 16    internal const float ALPHA_TRANSITION_STEP_PER_SECOND =  1f / 0.25f;
 17    internal const float ALPHA_STEPS = 32f;
 18    internal const float TARGET_ALPHA_SHOW = 1;
 19    internal const float TARGET_ALPHA_HIDE = 0;
 20    internal const int BACKGROUND_HEIGHT = 30;
 21    internal const int BACKGROUND_EXTRA_WIDTH = 10;
 22
 23    [SerializeField] internal Canvas canvas;
 24    [SerializeField] internal CanvasGroup canvasGroup;
 25    [SerializeField] internal TextMeshProUGUI nameText;
 26    [SerializeField] internal Image background;
 27    [SerializeField] internal Transform pivot;
 28    [SerializeField] internal Animator talkingAnimator;
 29
 30    [SerializeField] internal List<CanvasRenderer> canvasRenderers;
 31
 130232    internal BaseVariable<float> namesOpacity => DataStore.i.HUDs.avatarNamesOpacity;
 130233    internal BaseVariable<bool> namesVisible => DataStore.i.HUDs.avatarNamesVisible;
 34    internal BaseVariable<bool> profanityFilterEnabled;
 35
 36    internal bool forceShow = false;
 37    internal Color backgroundOriginalColor;
 44038    internal List<string> hideConstraints = new List<string>();
 44039    internal string currentName = "";
 40
 41    private float alpha;
 42    private float targetAlpha;
 43    private bool renderersVisible;
 44
 45
 46    internal float Alpha
 47    {
 048        get => alpha;
 49        set
 50        {
 351            alpha = Mathf.Clamp01(value);
 352            if (alpha < 0.01f)
 53            {
 254                UpdateVisuals(0);
 255                SetRenderersVisible(false);
 256                return;
 57            }
 58
 159            UpdateVisuals(alpha);
 160            SetRenderersVisible(true);
 161        }
 62    }
 63
 64    internal float TargetAlpha
 65    {
 066        get => targetAlpha;
 367        set => targetAlpha = Mathf.Clamp01(value);
 68    }
 69
 70
 71    private void Awake()
 72    {
 43473        backgroundOriginalColor = background.color;
 43474        canvas.sortingOrder = DEFAULT_CANVAS_SORTING_ORDER;
 43475        profanityFilterEnabled = DataStore.i.settings.profanityChatFilteringEnabled;
 43476        namesVisible.OnChange += OnNamesVisibleChanged;
 43477        namesOpacity.OnChange += OnNamesOpacityChanged;
 43478        profanityFilterEnabled.OnChange += OnProfanityFilterChanged;
 79
 43480        OnNamesVisibleChanged(namesVisible.Get(), true);
 43481        OnNamesOpacityChanged(namesOpacity.Get(), 1);
 43482        Show(true);
 43483    }
 88084    internal void OnNamesOpacityChanged(float current, float previous) { background.color = new Color(backgroundOriginal
 85
 87286    internal void OnNamesVisibleChanged(bool current, bool previous) { canvas.enabled = current || forceShow; }
 487    private void OnProfanityFilterChanged(bool current, bool previous) { SetName(currentName); }
 3088    public void SetName(string name) { AsyncSetName(name).Forget(); }
 89    private async UniTaskVoid AsyncSetName(string name)
 90    {
 1591        currentName = name;
 1592        name = await FilterName(currentName);
 1593        nameText.text = name;
 1594        background.rectTransform.sizeDelta = new Vector2(nameText.GetPreferredValues().x + BACKGROUND_EXTRA_WIDTH, BACKG
 1595    }
 96
 97    private async UniTask<string> FilterName(string name)
 98    {
 1599        return IsProfanityFilteringEnabled()
 100            ? await ProfanityFilterSharedInstances.regexFilter.Filter(name)
 101            : name;
 15102    }
 103
 104    private bool IsProfanityFilteringEnabled()
 105    {
 15106        return DataStore.i.settings.profanityChatFilteringEnabled.Get();
 107    }
 108
 94109    private void Update() { Update(Time.deltaTime); }
 110
 111    private void SetRenderersVisible(bool value)
 112    {
 518113        if (renderersVisible == value)
 65114            return;
 115
 3171116        canvasRenderers.ForEach(c => c.SetAlpha(value ? 1f : 0f));
 453117        renderersVisible = value;
 453118    }
 119
 120    internal void Update(float deltaTime)
 121    {
 50122        if (hideConstraints.Count > 0)
 123        {
 0124            UpdateVisuals(0);
 0125            return;
 126        }
 127
 50128        float finalTargetAlpha = forceShow ? TARGET_ALPHA_SHOW : targetAlpha;
 50129        alpha = Mathf.MoveTowards(alpha, finalTargetAlpha, ALPHA_TRANSITION_STEP_PER_SECOND * deltaTime);
 50130        if (CheckAndUpdateVisibility(alpha))
 2131            return;
 132
 48133        Vector3 cameraPosition = CommonScriptableObjects.cameraPosition.Get();
 48134        Vector3 cameraRight = CommonScriptableObjects.cameraRight.Get();
 48135        Quaternion cameraRotation = DataStore.i.camera.rotation.Get();
 136
 137        /*
 138         * TODO: We could obtain distance to player from the AvatarLODController but that coupling it's overkill and ugl
 139         * instead we should have a provider so all the subsystems can use it
 140         */
 48141        float distanceToCamera = Vector3.Distance(cameraPosition, gameObject.transform.position);
 48142        ScalePivotByDistance(distanceToCamera);
 48143        LookAtCamera(cameraRight, cameraRotation.eulerAngles);
 48144        pivot.transform.localPosition = Vector3.up * GetPivotYOffsetByDistance(distanceToCamera);
 145
 48146        float resolvedAlpha = forceShow ? TARGET_ALPHA_SHOW : ResolveAlphaByDistance(alpha, distanceToCamera, forceShow)
 48147        if (CheckAndUpdateVisibility(resolvedAlpha))
 0148            return;
 149
 48150        SetRenderersVisible(true);
 48151        float resolvedAlphaStep = GetNearestAlphaStep(resolvedAlpha);
 48152        float canvasAlphaStep = GetNearestAlphaStep(canvasGroup.alpha);
 153
 48154        if (resolvedAlphaStep != canvasAlphaStep)
 21155            UpdateVisuals(resolvedAlpha);
 156
 157
 158        // Local Methods
 159        bool CheckAndUpdateVisibility(float checkAlpha)
 160        {
 98161            if (checkAlpha < MINIMUM_ALPHA_TO_SHOW)
 162            {
 2163                if (renderersVisible)
 164                {
 0165                    UpdateVisuals(0);
 0166                    SetRenderersVisible(false);
 167                }
 2168                return true;
 169            }
 170
 96171            return false;
 172        }
 48173    }
 174
 175    internal void LookAtCamera(Vector3 cameraRight, Vector3 cameraEulerAngles)
 176    {
 49177        Transform cachedTransform = transform;
 49178        cachedTransform.right = -cameraRight; // This will set the Y rotation
 179
 180        // Now we use the negated X axis rotation to make the rotation steady in horizont
 49181        Vector3 finalEulerAngle = cachedTransform.localEulerAngles;
 49182        finalEulerAngle.x = -cameraEulerAngles.x;
 49183        cachedTransform.localEulerAngles = finalEulerAngle;
 49184    }
 185
 186    public void Show(bool instant = false)
 187    {
 452188        targetAlpha = TARGET_ALPHA_SHOW;
 452189        SetRenderersVisible(true);
 452190        if (instant)
 438191            alpha = TARGET_ALPHA_SHOW;
 452192    }
 193
 194    public void Hide(bool instant = false)
 195    {
 32196        targetAlpha = TARGET_ALPHA_HIDE;
 32197        if (instant && !forceShow)
 198        {
 15199            alpha = TARGET_ALPHA_HIDE;
 15200            SetRenderersVisible(false);
 201        }
 32202    }
 203
 204    // Note: Ideally we should separate the LODController logic from this one so we don't have to add constraints
 0205    public void AddVisibilityConstaint(string constraint) { hideConstraints.Add(constraint); }
 206
 0207    public void RemoveVisibilityConstaint(string constraint) { hideConstraints.Remove(constraint); }
 208
 209    public void SetForceShow(bool forceShow)
 210    {
 0211        canvas.enabled = forceShow || namesVisible.Get();
 0212        canvas.sortingOrder = forceShow ? FORCE_CANVAS_SORTING_ORDER : DEFAULT_CANVAS_SORTING_ORDER;
 0213        background.color = new Color(backgroundOriginalColor.r, backgroundOriginalColor.g, backgroundOriginalColor.b, fo
 0214        this.forceShow = forceShow;
 0215        if (this.forceShow)
 0216            SetRenderersVisible(true);
 0217    }
 218
 10219    public void SetIsTalking(bool talking) { talkingAnimator.SetBool(TALKING_ANIMATOR_BOOL, talking); }
 220
 10221    public void SetYOffset(float yOffset) { transform.localPosition = Vector3.up * yOffset; }
 222
 223    public Rect ScreenSpaceRect(Camera mainCamera)
 224    {
 0225        Vector3 origin = mainCamera.WorldToScreenPoint(background.transform.position);
 0226        Vector2 size = background.rectTransform.sizeDelta;
 0227        return new Rect(origin.x, Screen.height - origin.y, size.x, size.y);
 228    }
 229
 20230    public Vector3 ScreenSpacePos(Camera mainCamera) { return mainCamera.WorldToScreenPoint(background.transform.positio
 231
 232    internal static float ResolveAlphaByDistance(float alphaValue, float distanceToCamera, bool forceShow)
 233    {
 48234        if (forceShow)
 0235            return alphaValue;
 236
 237        const float MIN_DISTANCE = 5;
 48238        if (distanceToCamera < MIN_DISTANCE)
 48239            return alphaValue;
 240
 0241        return alphaValue * Mathf.Lerp(1, 0, (distanceToCamera - MIN_DISTANCE) / (DataStore.i.avatarsLOD.LODDistance.Get
 242    }
 243
 244    internal void UpdateVisuals(float resolvedAlpha)
 245    {
 24246        canvasGroup.alpha = resolvedAlpha;
 24247    }
 248
 249    internal float GetNearestAlphaStep(float alpha)
 250    {
 96251        return Mathf.Floor(alpha * ALPHA_STEPS);
 252    }
 253
 96254    internal void ScalePivotByDistance(float distanceToCamera) { pivot.transform.localScale = Vector3.one * 0.15f * dist
 255
 256    internal float GetPivotYOffsetByDistance(float distanceToCamera)
 257    {
 258        const float NEAR_Y_OFFSET = 0f;
 259        const float FAR_Y_OFFSET = 0.1f;
 260        const float MAX_DISTANCE = 5;
 48261        if (distanceToCamera >= MAX_DISTANCE)
 0262            return FAR_Y_OFFSET;
 263
 48264        return Mathf.Lerp(NEAR_Y_OFFSET, FAR_Y_OFFSET, distanceToCamera / MAX_DISTANCE);
 265    }
 266
 267    private void OnDestroy()
 268    {
 434269        namesVisible.OnChange -= OnNamesVisibleChanged;
 434270        namesOpacity.OnChange -= OnNamesOpacityChanged;
 434271        profanityFilterEnabled.OnChange -= OnProfanityFilterChanged;
 434272    }
 273}