using System; using UnityEngine; namespace Marro.PacManUdon { public class PelletManager : SyncedObject { public int PelletCount => pellets.Length; public int PelletCollectedCount { get; private set; } Pellet[] pellets; Animator[] powerPellets; bool powerPelletBlinkEnabled; float powerPelletBlinkToggleInterval; float powerPelletBlinkProgress; bool powerPelletBlinkCurrentlyVisible; byte[] syncedPelletsCollected; public void Initialize() { gameObject.SetActive(true); pellets = GetComponentsInChildren(includeInactive: true); powerPellets = GetComponentsInChildren(true); powerPelletBlinkToggleInterval = PacManConstants.GetPowerPelletBlinkToggleInterval(); SetPowerPelletsBlink(false); RestoreAllPellets(); } public override void SyncedUpdate() { if (!powerPelletBlinkEnabled) { return; } powerPelletBlinkProgress += networkManager.SyncedDeltaTime; if (powerPelletBlinkProgress >= powerPelletBlinkToggleInterval) { // Debug.Log($"{gameObject} PowerPelletBlink toggle"); powerPelletBlinkProgress -= powerPelletBlinkToggleInterval; powerPelletBlinkCurrentlyVisible = !powerPelletBlinkCurrentlyVisible; SetPowerPelletsVisible(powerPelletBlinkCurrentlyVisible); } } void SetPowerPelletsVisible(bool visible) { // Debug.Log($"{gameObject} SetPowerPelletVisible {visible}, powerPellets.Length: {powerPellets.Length}"); foreach (Animator powerPellet in powerPellets) { powerPellet.SetBool("Visible", visible); } } public void SetPowerPelletsBlink(bool enabled) { // Debug.Log($"{gameObject} SetPowerPelletBlink {enabled}"); powerPelletBlinkEnabled = enabled; powerPelletBlinkCurrentlyVisible = true; powerPelletBlinkProgress = 0; SetPowerPelletsVisible(true); } public void FreezePowerPelletsBlink(bool frozen) { powerPelletBlinkEnabled = !frozen; } public int PelletCollected(Pellet pellet) { pellet.gameObject.SetActive(false); var index = pellet.transform.GetSiblingIndex(); syncedPelletsCollected[index/8] |= (byte)(1 << index%8); PelletCollectedCount++; return PelletCollectedCount; } public int RestoreAllPellets() { foreach (var pellet in pellets) { pellet.gameObject.SetActive(true); } syncedPelletsCollected = new byte[pellets.Length/8 + 1]; PelletCollectedCount = 0; return PelletCount; } private void SetPelletsCollectedFromSync() { for (int i = 0; i < pellets.Length; i++) { var active = (syncedPelletsCollected[i/8] & (byte)(1 << i%8)) == 0; pellets[i].gameObject.SetActive(active); } } public override void CollectSyncedData(byte[] data, ref int index, NetworkEventType eventType) { if (eventType != NetworkEventType.SyncPellets) { return; } data.Append((byte)PelletCollectedCount, ref index); data.Append(syncedPelletsCollected, ref index); } public override bool WriteSyncedData(byte[] data, ref int index, NetworkEventType eventType) { if (eventType != NetworkEventType.SyncPellets) { return true; } PelletCollectedCount = data.ReadByte(ref index); Array.Copy(data, index, syncedPelletsCollected, 0, syncedPelletsCollected.Length); index += syncedPelletsCollected.Length; SetPelletsCollectedFromSync(); return true; } } }