< Summary

Class:XRButton
Assembly:Test
File(s):E:/Unity/Unity Project/VR-Basics/Assets/_Course Library/Scripts/Core/XRButton.cs
Covered lines:70
Uncovered lines:17
Coverable lines:87
Total lines:187
Line coverage:80.4% (70 of 87)
Covered branches:0
Total branches:0
Covered methods:14
Total methods:15
Method coverage:93.3% (14 of 15)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
XRButton()0%000100%
OnEnable()0%000100%
OnDisable()0%000100%
StartPress(...)0%000100%
EndPress(...)0%000100%
Start()0%000100%
SetMinMax()0%000100%
ProcessInteractable(...)0%00060%
FindButtonHeight()0%000100%
GetLocalYPosition(...)0%000100%
ApplyHeight(...)0%000100%
SetButtonPosition(...)0%000100%
CheckPress()0%00028.57%
InPosition()0%000100%
IsSelectableBy(...)0%0000%

File(s)

E:/Unity/Unity Project/VR-Basics/Assets/_Course Library/Scripts/Core/XRButton.cs

#LineLine coverage
 1using System.Diagnostics.CodeAnalysis;
 2using UnityEngine;
 3using UnityEngine.Events;
 4using UnityEngine.XR.Interaction.Toolkit;
 5using HenryLab;
 6
 7/// <summary>
 8/// An interactable that can be pressed by a direct interactor
 9/// </summary>
 10public class XRButton : XRBaseInteractable, ITriggerableEntity
 11{
 12    [ExcludeFromCodeCoverage] public float TriggeringTime => 2.5f;
 13    [ExcludeFromCodeCoverage] public string Name => Str.Triggerable;
 14
 15    [ExcludeFromCodeCoverage]
 16    public void Triggerring()
 17    {
 18        var obj = EntityManager.Instance.vrexplorerMono.gameObject;
 19        XRDirectInteractor interactor;
 20        if(!obj.TryGetComponent(out interactor))
 21        {
 22            interactor = obj.AddComponent<XRDirectInteractor>();
 23        }
 24        if(!obj.GetComponent<ActionBasedController>())
 25        {
 26            obj.AddComponent<ActionBasedController>();
 27        }
 28
 29        buttonTransform = transform;
 30        StartPress(new HoverEnterEventArgs() { interactorObject = interactor });
 31        float height = FindButtonHeight();
 32        ApplyHeight(height);
 33        OnPress?.Invoke();
 34
 35    }
 36
 37    [ExcludeFromCodeCoverage]
 38    public void Triggerred()
 39    {
 40        var obj = EntityManager.Instance.vrexplorerMono.gameObject;
 41        XRDirectInteractor interactor;
 42        if(!obj.TryGetComponent(out interactor))
 43        {
 44            interactor = obj.AddComponent<XRDirectInteractor>();
 45        }
 46        if(!obj.GetComponent<ActionBasedController>())
 47        {
 48            obj.AddComponent<ActionBasedController>();
 49        }
 50
 51        EndPress(new HoverExitEventArgs() { interactorObject = interactor });
 52        OnRelease?.Invoke();
 53    }
 54
 55    [Tooltip("The transform of the visual component of the button")]
 856    public Transform buttonTransform = null;
 57
 58    [Tooltip("The distance the button can be pressed")]
 859    public float pressDistance = 0.1f;
 60
 61    // When the button is pressed
 862    public UnityEvent OnPress = new UnityEvent();
 63
 64    // When the button is released
 865    public UnityEvent OnRelease = new UnityEvent();
 66
 867    private float yMin = 0.0f;
 868    private float yMax = 0.0f;
 69
 870    private IXRHoverInteractor hoverInteractor = null;
 71
 872    private float hoverHeight = 0.0f;
 873    private float startHeight = 0.0f;
 874    private bool previousPress = false;
 75
 76
 77
 78    protected override void OnEnable()
 479    {
 480        base.OnEnable();
 481        hoverEntered.AddListener(StartPress);
 482        hoverExited.AddListener(EndPress);
 483    }
 84
 85    protected override void OnDisable()
 486    {
 487        base.OnDisable();
 488        hoverEntered.RemoveListener(StartPress);
 489        hoverExited.RemoveListener(EndPress);
 490    }
 91
 92    private void StartPress(HoverEnterEventArgs eventArgs)
 493    {
 494        hoverInteractor = eventArgs.interactorObject;
 495        hoverHeight = GetLocalYPosition(hoverInteractor.transform.position);
 496        startHeight = buttonTransform.localPosition.y;
 497    }
 98
 99    private void EndPress(HoverExitEventArgs eventArgs)
 4100    {
 4101        hoverInteractor = null;
 4102        hoverHeight = 0.0f;
 4103        startHeight = 0.0f;
 4104        ApplyHeight(yMax);
 4105    }
 106
 107    private void Start()
 4108    {
 4109        SetMinMax();
 4110    }
 111
 112    private void SetMinMax()
 4113    {
 4114        yMin = buttonTransform.localPosition.y - pressDistance;
 4115        yMax = buttonTransform.localPosition.y;
 4116    }
 117
 118    public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
 21144119    {
 21144120        if(updatePhase == XRInteractionUpdateOrder.UpdatePhase.Dynamic)
 2872121        {
 2872122            if(isHovered)
 0123            {
 0124                float height = FindButtonHeight();
 0125                ApplyHeight(height);
 0126            }
 2872127        }
 21144128    }
 129
 130    private float FindButtonHeight()
 4131    {
 4132        float newHoverHeight = GetLocalYPosition(hoverInteractor.transform.position);
 4133        float hoverDifference = hoverHeight - newHoverHeight;
 4134        return startHeight - hoverDifference;
 4135    }
 136
 137    private float GetLocalYPosition(Vector3 position)
 8138    {
 8139        Vector3 localPosition = transform.InverseTransformPoint(position);
 8140        return localPosition.y;
 8141    }
 142
 143    private void ApplyHeight(float position)
 8144    {
 8145        SetButtonPosition(position);
 8146        CheckPress();
 8147    }
 148
 149    private void SetButtonPosition(float position)
 8150    {
 8151        Vector3 newPosition = buttonTransform.localPosition;
 8152        newPosition.y = Mathf.Clamp(position, yMin, yMax);
 8153        buttonTransform.localPosition = newPosition;
 8154    }
 155
 156    private void CheckPress()
 8157    {
 8158        bool inPosition = InPosition();
 159
 8160        if(inPosition != previousPress)
 0161        {
 0162            previousPress = inPosition;
 163
 0164            if(inPosition)
 0165            {
 0166                OnPress.Invoke();
 0167            }
 168            else
 0169            {
 0170                OnRelease.Invoke();
 0171            }
 0172        }
 8173    }
 174
 175    private bool InPosition()
 8176    {
 8177        float threshold = yMin + (pressDistance * 0.5f);
 8178        return buttonTransform.localPosition.y < threshold;
 8179    }
 180
 181    public override bool IsSelectableBy(IXRSelectInteractor interactor)
 0182    {
 0183        return false;
 0184    }
 185
 186
 187}