using UnityEngine; namespace Ashwild.Network { /// /// Base for every local (non-networked) world object whose multiplayer state is tracked by a /// WorldObjectRegistry through a baked id — pickups, harvestables, and future destructibles. /// The object itself never replicates; the registry syncs only "active / inactive" by id, which /// scales to thousands. Scene objects get a baked id (>= 0) via the id tool; runtime objects /// (e.g. drops) get a negative id assigned at spawn. /// public abstract class WorldObject : MonoBehaviour { #region Serialized Fields [Header("Identity")] [Tooltip("Baked scene id (>= 0), assigned by Tools ▸ Ashwild ▸ Assign World Object IDs. Runtime objects get a negative id.")] [SerializeField] private int id = -1; #endregion #region Public API /// /// Scene id (>= 0) or runtime id (< 0), used by the registry to track this object. /// public int Id => id; /// /// Removes this object from the world (claimed / depleted). is true /// for a real transition (play effects/sounds) and false for catch-up on a late join (silent). /// public virtual void HideAsInactive(bool fresh) => gameObject.SetActive(false); /// /// Brings this object back into the world (respawn). Override to reset state. /// public virtual void ShowActive() => gameObject.SetActive(true); #endregion #region Subclass Hooks /// /// Whether this object should register itself with its registry on Start (scene objects do; /// runtime instances managed by the registry can opt out). /// protected virtual bool ShouldAutoRegister => true; /// /// Returns the registry this object belongs to (the type-specific singleton). /// protected abstract WorldObjectRegistry GetRegistry(); /// /// Assigns the id at runtime (used by registries for spawned instances such as drops). /// protected void SetId(int value) => id = value; #endregion #region Unity Lifecycle /// /// Self-registers scene objects with their registry once it exists. /// protected virtual void Start() { if (!ShouldAutoRegister) return; WorldObjectRegistry registry = GetRegistry(); if (registry != null) registry.RegisterObject(this); } #endregion } }