using UdonSharp; using UnityEngine; [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class CameraTimedSwitcher : UdonSharpBehaviour { [SerializeField] private CameraControllerBase _CameraController; [SerializeField] private string[] _SwitchFunctions; [SerializeField] private float[] _TimeBetweenCuts = { 5.0f }; [Space] [SerializeField] private bool _Loop = true; [SerializeField, Tooltip("Loop to this point in the camera sequence. Default is index 0 (the beginning)")] private int _LoopPoint = 0; [Space] [SerializeField, Tooltip("Set this to call a function on an UdonSharpBehaviour instead of looping the camera sequence")] private UdonSharpBehaviour _FirstLoopCallbackObject = null; [SerializeField] private string _FirstLoopCallbackFunction = ""; [UdonSynced, FieldChangeCallback(nameof(Activate))] private bool _Active = false; private int _NextCameraIndex = 0; private bool _LoopedOnce = false; public void SwitchToNextCamera() { if (_Active) { int CurrentCameraIndex = _NextCameraIndex; if (CurrentCameraIndex == _LoopPoint && _LoopedOnce) { if (_FirstLoopCallbackObject != null) { _FirstLoopCallbackObject.SendCustomEvent(_FirstLoopCallbackFunction); Activate = false; return; } if (!_Loop) { Activate = false; return; } } string Function = _SwitchFunctions[_NextCameraIndex]; if (Function != "") { _CameraController.SendCustomEvent(Function); } _NextCameraIndex = (_NextCameraIndex + 1) % _SwitchFunctions.Length; if (_NextCameraIndex == 0) { _LoopedOnce = true; _NextCameraIndex = _LoopPoint; } SendCustomEventDelayedSeconds(nameof(SwitchToNextCamera), _TimeBetweenCuts[Mathf.Min(CurrentCameraIndex, _TimeBetweenCuts.Length - 1)]); } } public bool Activate { set { if (_Active != value) { _Active = value; _NextCameraIndex = 0; _LoopedOnce = false; SwitchToNextCamera(); RequestSerialization(); } } get => _Active; } }