using UdonSharp; using UnityEngine; using VRC.SDK3.Data; namespace Marro.PacManUdon { [RequireComponent(typeof(Animator))] [RequireComponent(typeof(Renderer))] public class BonusFruit : SyncedObject { private PacManFruitType fruitType; private Animator animator; private new Renderer renderer; private ScoreBonusDisplay scoreBonusDisplay; private bool active; private float activeCountdown; private int value; private bool frozen; public void Initialize() { animator = GetComponent(); renderer = GetComponent(); scoreBonusDisplay = transform.Find("ScoreBonusDisplay").gameObject.GetComponent(); scoreBonusDisplay.Initialize(); SetActive(false); } public override void SyncedUpdate() { if (!active || frozen) { return; } activeCountdown -= networkManager.SyncedDeltaTime; if (activeCountdown <= 0) { SetActive(false); } } public void Spawn() { // Debug.Log($"{gameObject} Spawned"); SetActive(true); activeCountdown = Random.Range(9, 10); } public void Despawn() { // Debug.Log($"{gameObject} Despawned"); SetActive(false); } public int Collected() { SetActive(false); scoreBonusDisplay.DisplayTemporarily(value, 1); return value; } public void SetFruitType(PacManFruitType fruitType) { value = (int)fruitScoreValue[PacManConstants.FruitTypeToValue(fruitType)]; animator.SetFloat("FruitType", PacManConstants.FruitTypeToValue(fruitType)); } public void SetFrozen(bool frozen) { this.frozen = frozen; } void SetActive(bool active) { // This replaces GameObject.active, as attempting to update an animator while a gameobject is inactive seems to result in a silent failure renderer.enabled = active; this.active = active; } public override void CollectSyncedData(byte[] data, ref int index, NetworkEventType eventType) { data.Append(active, ref index); if (!active) { return; } data.Append(activeCountdown, ref index); data.Append(frozen, ref index); } public override bool WriteSyncedData(byte[] data, ref int index, NetworkEventType eventType) { SetActive(data.ReadBool(ref index)); if (!active) { return true; } activeCountdown = data.ReadFloat(ref index); frozen = data.ReadBool(ref index); return true; } public bool Active => active; private readonly DataDictionary fruitScoreValue = new DataDictionary() { {(int)PacManFruitType.None , 0}, {(int)PacManFruitType.Cherries , 100}, {(int)PacManFruitType.Strawberry, 300}, {(int)PacManFruitType.Peach , 500}, {(int)PacManFruitType.Apple , 700}, {(int)PacManFruitType.Grapes , 1000}, {(int)PacManFruitType.Galaxian , 2000}, {(int)PacManFruitType.Bell , 3000}, {(int)PacManFruitType.Key , 5000} }; } }