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;
}
}
}