#if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; using UnityEngine.UI; namespace ClusterVR.CreatorKit.World.Implements.PlayerLocalUI { [RequireComponent(typeof(Canvas), typeof(CanvasScaler)), DisallowMultipleComponent, ExecuteAlways] public sealed class PlayerLocalUI : MonoBehaviour, IPlayerLocalUI { [SerializeField, HideInInspector] RectTransform rectTransform; [SerializeField, HideInInspector] Canvas canvas; [SerializeField] PlayerLocalUISortingOrder sortingOrderType = PlayerLocalUISortingOrder.Default; PlayerLocalUISortingOrder IPlayerLocalUI.SortingOrder => sortingOrderType; RectTransform IPlayerLocalUI.RectTransform { get { if (rectTransform != null) { return rectTransform; } if (this == null) { return null; } return rectTransform = GetComponent(); } } Canvas Canvas { get { if (canvas != null) { return canvas; } if (this == null) { return null; } return canvas = GetComponent(); } } public void SetEnabled(bool enabled) { var canvas = Canvas; if (canvas != null) { canvas.enabled = enabled; } } void Start() { SetupCanvasScaler(); } void SetupCanvasScaler() { var canvasScaler = GetComponent(); canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; canvasScaler.referenceResolution = new Vector2(1024, 768); canvasScaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight; canvasScaler.matchWidthOrHeight = 0.5f; canvasScaler.referencePixelsPerUnit = 100f; } void OnValidate() { if (rectTransform == null || rectTransform.gameObject != gameObject) { rectTransform = GetComponent(); } if (canvas == null || canvas.gameObject != gameObject) { canvas = GetComponent(); } var selectables = GetComponentsInChildren(true); foreach (var selectable in selectables) { var navigation = new Navigation { mode = Navigation.Mode.None }; selectable.navigation = navigation; } LimitSortingOrders(); } void LimitSortingOrders() { if (canvas == null) { return; } canvas.renderMode = canvas.renderMode switch { RenderMode.ScreenSpaceOverlay => RenderMode.ScreenSpaceOverlay, RenderMode.ScreenSpaceCamera => RenderMode.ScreenSpaceOverlay, RenderMode.WorldSpace => RenderMode.WorldSpace, _ => RenderMode.ScreenSpaceOverlay, }; LimitSortingOrder(canvas); foreach (var childCanvas in gameObject.GetComponentsInChildren(true)) { if (childCanvas.overrideSorting) { LimitSortingOrder(childCanvas); } } } void LimitSortingOrder(Canvas canvas) { if (canvas.renderMode == RenderMode.WorldSpace) { canvas.sortingOrder = 0; } else { if (canvas.sortingOrder > 100) { canvas.sortingOrder = 100; } else if (canvas.sortingOrder < -100) { canvas.sortingOrder = -100; } } } void Reset() { rectTransform = GetComponent(); canvas = GetComponent(); #if UNITY_EDITOR void CreateSafeAreaIfNot() { foreach (Transform child in transform) { if (child.GetComponent() != null) { return; } } var safeArea = ObjectFactory.CreateGameObject("SafeArea", typeof(SafeArea)); safeArea.transform.SetParent(transform); } CreateSafeAreaIfNot(); #endif } } }