- Refactored CameraTimedSwitcher to use an internal timer instead of delays.

- Added extra switchers to rounds 1 and 2 to better control camera transitions.
- Fixed improper camera switches on incorrect answers during round 2.
This commit is contained in:
2026-03-24 05:16:30 -04:00
parent 15cf4be640
commit 001be2af0e
20 changed files with 1129 additions and 521 deletions
@@ -44,7 +44,7 @@ MonoBehaviour:
Data:
- Name:
Entry: 12
Data: 10
Data: 12
- Name:
Entry: 7
Data:
@@ -543,19 +543,13 @@ MonoBehaviour:
Data: 36|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 2
Data: 1
- Name:
Entry: 7
Data: 37|UdonSharp.UdonSyncedAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data: 38|UdonSharp.FieldChangeCallbackAttribute, UdonSharp.Runtime
- Name:
Entry: 8
Data:
- Name:
Entry: 13
Data:
@@ -573,19 +567,25 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
Data: _NextCameraIndex
Data: _Timer
- Name: $v
Entry: 7
Data: 39|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
Data: 38|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _NextCameraIndex
Data: _Timer
- Name: <UserType>k__BackingField
Entry: 9
Data: 21
Entry: 7
Data: 39|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: System.Single, mscorlib
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 21
Data: 39
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
@@ -621,13 +621,13 @@ MonoBehaviour:
Data:
- Name: $k
Entry: 1
Data: _LoopedOnce
Data: _AwaitingNextSwitch
- Name: $v
Entry: 7
Data: 41|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _LoopedOnce
Data: _AwaitingNextSwitch
- Name: <UserType>k__BackingField
Entry: 9
Data: 16
@@ -664,6 +664,102 @@ MonoBehaviour:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _NextCameraIndex
- Name: $v
Entry: 7
Data: 43|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _NextCameraIndex
- Name: <UserType>k__BackingField
Entry: 9
Data: 21
- Name: <SystemType>k__BackingField
Entry: 9
Data: 21
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 44|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _LoopedOnce
- Name: $v
Entry: 7
Data: 45|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _LoopedOnce
- Name: <UserType>k__BackingField
Entry: 9
Data: 16
- Name: <SystemType>k__BackingField
Entry: 9
Data: 16
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 46|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 13
Data:
@@ -1,6 +1,8 @@
using Newtonsoft.Json.Linq;
using UdonSharp;
using UnityEngine;
using VRC.Udon.Common;
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
@@ -18,29 +20,81 @@ public class CameraTimedSwitcher : UdonSharpBehaviour
private UdonSharpBehaviour _FirstLoopCallbackObject = null;
[SerializeField] private string _FirstLoopCallbackFunction = "";
[UdonSynced, FieldChangeCallback(nameof(Activate))] private bool _Active = false;
[UdonSynced] private bool _Active = false;
private float _Timer = 0.0f;
private bool _AwaitingNextSwitch = false;
private int _NextCameraIndex = 0;
private bool _LoopedOnce = false;
void Update()
{
if (_Active && _AwaitingNextSwitch)
{
_Timer -= Time.deltaTime;
if (_Timer <= 0.0f)
{
SwitchToNextCamera();
}
}
}
public override void OnDeserialization(DeserializationResult Result)
{
_Activate_Synced();
base.OnDeserialization(Result);
}
public void Activate(bool Activate)
{
_Active = Activate;
_Activate_Synced();
RequestSerialization();
}
private void _Activate_Synced()
{
Debug.Log("[CameraTimedSwitcher] " + gameObject.name + " is now " + (_Active ? "active" : "inactive"));
_AwaitingNextSwitch = false;
if (_Active)
{
_NextCameraIndex = 0;
_LoopedOnce = false;
SwitchToNextCamera();
}
else
{
_Timer = 0.0f;
}
}
public void SwitchToNextCamera()
{
_AwaitingNextSwitch = false;
if (_Active)
{
int CurrentCameraIndex = _NextCameraIndex;
Debug.Log("[CameraTimedSwitcher] Current camera index: " + CurrentCameraIndex);
if (CurrentCameraIndex == _LoopPoint && _LoopedOnce)
{
if (_FirstLoopCallbackObject != null)
{
Debug.Log("[CameraTimedSwitcher] We're on a new loop and a callback is set; running function " + _FirstLoopCallbackFunction + " on object " + _FirstLoopCallbackObject.gameObject.name + " and deactivating");
_FirstLoopCallbackObject.SendCustomEvent(_FirstLoopCallbackFunction);
Activate = false;
Activate(false);
return;
}
if (!_Loop)
{
Activate = false;
Debug.Log("[CameraTimedSwitcher] On a second loop, but looping is disabled; deactivating");
Activate(false);
return;
}
}
@@ -49,6 +103,7 @@ public class CameraTimedSwitcher : UdonSharpBehaviour
if (Function != "")
{
_CameraController.SendCustomEvent(Function);
Debug.Log("[CameraTimedSwitcher] Executing function " + Function);
}
_NextCameraIndex = (_NextCameraIndex + 1) % _SwitchFunctions.Length;
@@ -57,30 +112,12 @@ public class CameraTimedSwitcher : UdonSharpBehaviour
{
_LoopedOnce = true;
_NextCameraIndex = _LoopPoint;
Debug.Log("[CameraTimedSwitcher] Setting next camera index to loop point " + _LoopPoint);
}
SendCustomEventDelayedSeconds(nameof(SwitchToNextCamera),
_TimeBetweenCuts[Mathf.Min(CurrentCameraIndex, _TimeBetweenCuts.Length - 1)]);
_Timer = _TimeBetweenCuts[Mathf.Min(CurrentCameraIndex, _TimeBetweenCuts.Length - 1)];
_AwaitingNextSwitch = true;
Debug.Log("[CameraTimedSwitcher] Camera index " + _NextCameraIndex + " will be activated in " + _Timer + " seconds");
}
}
public bool Activate
{
set
{
if (_Active != value)
{
Debug.Log("[CameraTimedSwitcher] " + gameObject.name + " is now " + (_Active ? "active" : "inactive"));
_Active = value;
_NextCameraIndex = 0;
_LoopedOnce = false;
SwitchToNextCamera();
RequestSerialization();
}
}
get => _Active;
}
}