using UdonSharp; using UnityEngine; using VRC.SDKBase; using VRC.Udon; using VRC.Udon.Common; [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class TimerOverlay : UdonSharpBehaviour { [SerializeField] private Animator _Animator; [SerializeField] private GameObject _OverlayElements; [UdonSynced] private bool _OverlayElementsEnabled = false; [UdonSynced] private bool _FadeOutAnimation = false; private Camera _Camera = null; private const float ASPECT_16_9 = 1.7777777777777777777777777777777777777f; private const float NEAR_PLANE_OFFSET = 0.0001f; void Update() { if (transform.parent != null) { if (_Camera != null) { _UpdateCameraSettings(); return; } Camera ParentCamera = GetComponentInParent(); if (ParentCamera) { _Camera = ParentCamera; transform.localRotation = Quaternion.identity; _UpdateCameraSettings(); } else { _Camera = null; } } } public override void OnDeserialization(DeserializationResult Result) { _EnableOverlayElements_Synced(); _PlayFadeOutAnimation_Synced(); base.OnDeserialization(Result); } public void EnableOverlayElements(bool Enable) { _OverlayElementsEnabled = Enable; _EnableOverlayElements_Synced(); _FadeOutAnimation = false; _PlayFadeOutAnimation_Synced(); RequestSerialization(); } private void _EnableOverlayElements_Synced() { _OverlayElements.SetActive(_OverlayElementsEnabled); } public void PlayFadeOutAnimation() { _FadeOutAnimation = true; _PlayFadeOutAnimation_Synced(); RequestSerialization(); } private void _PlayFadeOutAnimation_Synced() { _Animator.SetBool("Fade Out Elements", _FadeOutAnimation); } private void _UpdateCameraSettings() { Vector3 Position = Vector3.zero; Position.z = _Camera.nearClipPlane + NEAR_PLANE_OFFSET; transform.localPosition = Position; Vector3 Scale = Vector3.one; Scale.y = 2.0f * Position.z * Mathf.Tan(_Camera.fieldOfView * 0.5f * Mathf.Deg2Rad); Scale.x = Scale.y * ASPECT_16_9; transform.localScale = Scale; } }