using System; using UnityEngine; using UnityEngine.UI; #if XR_ITK using UnityEngine.XR.Interaction.Toolkit.UI; #elif META_SDK using Oculus.Interaction; using Oculus.Interaction.Surfaces; #endif namespace VRUIP { /// /// This class is an abstract class that will setup any canvas for this package to work with the VR rig's camera. /// public abstract class A_Canvas : A_ColorController { // COMPONENTS [SerializeField] private Canvas canvas; private CanvasGroup _canvasGroup; private RectTransform _rectTransform; private bool _isTransitioning; private Camera _camera; public bool IsSetup { get; private set; } = false; protected RectTransform RectTransform => _rectTransform; public Canvas Canvas => canvas; public Camera Camera => _camera; protected override void Start() { base.Start(); if (!IsSetup) Setup(); } /// /// Setup this canvas. /// public void Setup() { IsSetup = true; canvas.worldCamera = _camera = VRUIPManager.instance.mainCamera; _rectTransform = canvas.GetComponent(); SetupCanvasForFramework(); SetupCanvasGroup(); } /// /// Setup this canvas based on the user's selected target framework. /// private void SetupCanvasForFramework() { #if XR_ITK if (canvas.TryGetComponent(out var graphicRaycaster)) { Destroy(graphicRaycaster); } if (canvas.GetComponent() != null) return; canvas.gameObject.AddComponent(); #elif OCULUS_INTEGRATION if (canvas.TryGetComponent(out var graphicRaycaster)) { Destroy(graphicRaycaster); } if (canvas.GetComponent() != null) return; var ovrRaycaster = canvas.gameObject.AddComponent(); ovrRaycaster.pointer = VRUIPManager.instance.laserPointer.gameObject; #elif META_SDK var graphicRaycaster = canvas.GetComponent(); var pointableCanvas = canvas.GetComponent(); var boxCollider = canvas.GetComponent(); var colliderSurface = canvas.GetComponent(); var rayInteractable = canvas.GetComponent(); if (graphicRaycaster == null) { canvas.gameObject.AddComponent(); } if (pointableCanvas == null) { pointableCanvas = canvas.gameObject.AddComponent(); pointableCanvas.InjectCanvas(canvas); } if (boxCollider == null) { boxCollider = canvas.gameObject.AddComponent(); var z = 1 / (1 / canvas.transform.localScale.z * 1000f); boxCollider.size = new Vector3(_rectTransform.rect.size.x, _rectTransform.rect.size.y, z); } if (colliderSurface == null) { colliderSurface = canvas.gameObject.AddComponent(); colliderSurface.InjectCollider(boxCollider); } if (rayInteractable == null) { rayInteractable = canvas.gameObject.AddComponent(); rayInteractable.InjectSurface(colliderSurface); rayInteractable.InjectOptionalPointableElement(pointableCanvas); } #else if (canvas.GetComponent() != null) return; canvas.gameObject.AddComponent(); #endif } /// /// Setup the canvas group for this canvas. /// private void SetupCanvasGroup() { if (_canvasGroup != null) return; _canvasGroup = canvas.GetComponent(); if (_canvasGroup == null) { _canvasGroup = canvas.gameObject.AddComponent(); } } /// /// Fade out this canvas and do something when fading finishes. /// public void FadeOutCanvas(Action callback = null) { if (_isTransitioning) return; if (_canvasGroup.gameObject.activeInHierarchy == false) return; _isTransitioning = true; StartCoroutine(_canvasGroup.TransitionAlpha(0, 4, () => { callback?.Invoke(); _isTransitioning = false; gameObject.SetActive(false); })); } /// /// Fade in this canvas and do something when fading finishes. /// public void FadeInCanvas(Action callback = null) { if (_isTransitioning) return; _isTransitioning = true; gameObject.SetActive(true); StartCoroutine(_canvasGroup.TransitionAlpha(1, 4, () => { callback?.Invoke(); _isTransitioning = false; })); } /// /// Set alpha of canvas group. /// public void SetAlpha(float alpha) { if (!IsSetup) SetupCanvasGroup(); _canvasGroup.alpha = alpha; } } }