using System; using UdonSharp; using UnityEngine; using VRC.SDK3.UdonNetworkCalling; using VRC.SDKBase; using VRC.Udon; using VRC.Udon.Common; using VRC.Udon.Serialization.OdinSerializer.Utilities; [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class FilingCabinet : UdonSharpBehaviour { [SerializeField] private Animator _Animator; [SerializeField] private GameObject[] _DrawerHandleTriggers; [SerializeField] private FilingCabinetNoteDispenser[] _NoteDispensers; [UdonSynced, FieldChangeCallback(nameof(Activate))] private bool _Activate = false; [UdonSynced] public string[] ClueNotes = new string[DRAWER_COUNT] { "", "", "", "" }; [UdonSynced] public int[] ClueImages = new int[DRAWER_COUNT] { -1, -1, -1, -1 }; [UdonSynced] public float[] ClueImageScales = new float[DRAWER_COUNT] { 1.0f, 1.0f, 1.0f, 1.0f }; private bool[] DrawerIsOpen = new bool[DRAWER_COUNT] { false, false, false, false }; private string[] _ClueNotesCache = new string[DRAWER_COUNT]; private int[] _ClueImagesCache = new int[DRAWER_COUNT]; private float[] _ClueImageScalesCache = new float[DRAWER_COUNT]; public const int DRAWER_COUNT = 4; private const float NOTE_DISPENSER_ACTIVATE_DELAY = 0.5f; public override void OnDeserialization(DeserializationResult Result) { bool NotesChanged = false; for (int i = 0; i < DRAWER_COUNT; i++) { if (ClueNotes[i] != _ClueNotesCache[i] || ClueImages[i] != _ClueImagesCache[i] || ClueImageScales[i] != _ClueImageScalesCache[i]) { NotesChanged = true; break; } } if (NotesChanged) { UpdateNoteData(); } base.OnDeserialization(Result); } [NetworkCallable] public void OpenDrawer1() { DrawerIsOpen[0] = !_Animator.GetBool("Open Drawer 1"); _Animator.SetBool("Open Drawer 1", DrawerIsOpen[0]); if (Utilities.IsValid(_NoteDispensers[0])) { if (DrawerIsOpen[0]) { SendCustomEventDelayedSeconds(nameof(ActivateNoteDispenser1), NOTE_DISPENSER_ACTIVATE_DELAY); } else { ActivateNoteDispenser1(); } } } [NetworkCallable] public void OpenDrawer2() { DrawerIsOpen[1] = !_Animator.GetBool("Open Drawer 2"); _Animator.SetBool("Open Drawer 2", DrawerIsOpen[1]); if (Utilities.IsValid(_NoteDispensers[1])) { if (DrawerIsOpen[1]) { SendCustomEventDelayedSeconds(nameof(ActivateNoteDispenser2), NOTE_DISPENSER_ACTIVATE_DELAY); } else { ActivateNoteDispenser2(); } } } [NetworkCallable] public void OpenDrawer3() { DrawerIsOpen[2] = !_Animator.GetBool("Open Drawer 3"); _Animator.SetBool("Open Drawer 3", DrawerIsOpen[2]); if (Utilities.IsValid(_NoteDispensers[2])) { if (DrawerIsOpen[2]) { SendCustomEventDelayedSeconds(nameof(ActivateNoteDispenser3), NOTE_DISPENSER_ACTIVATE_DELAY); } else { ActivateNoteDispenser3(); } } } [NetworkCallable] public void OpenDrawer4() { DrawerIsOpen[3] = !_Animator.GetBool("Open Drawer 4"); _Animator.SetBool("Open Drawer 4", DrawerIsOpen[3]); if (Utilities.IsValid(_NoteDispensers[3])) { if (DrawerIsOpen[3]) { SendCustomEventDelayedSeconds(nameof(ActivateNoteDispenser4), NOTE_DISPENSER_ACTIVATE_DELAY); } else { ActivateNoteDispenser4(); } } } public void UpdateNoteData() { for (int i = 0; i < _NoteDispensers.Length && i < DRAWER_COUNT; i++) { _NoteDispensers[i].Note = ClueNotes[i]; _NoteDispensers[i].Image = ClueImages[i]; _NoteDispensers[i].ImageScale = ClueImageScales[i]; _NoteDispensers[i].RequestSerialization(); } _ClueNotesCache = ClueNotes; _ClueImagesCache = ClueImages; _ClueImageScalesCache = ClueImageScales; } public void ActivateNoteDispenser1() { _NoteDispensers[0].Activate = DrawerIsOpen[0]; } public void ActivateNoteDispenser2() { _NoteDispensers[1].Activate = DrawerIsOpen[1]; } public void ActivateNoteDispenser3() { _NoteDispensers[2].Activate = DrawerIsOpen[2]; } public void ActivateNoteDispenser4() { _NoteDispensers[3].Activate = DrawerIsOpen[3]; } public bool Activate { set { _Activate = value; foreach(GameObject Trigger in _DrawerHandleTriggers) { Trigger.SetActive(_Activate); } } get => _Activate; } }