using System; using System.Linq; using UnityEngine; namespace MoreMountains.Tools { /// /// A base class implementing the IMMPersistent interface, designed to be extended /// This mostly takes care of the GUID generation and validation /// [AddComponentMenu("")] public class MMPersistentBase : MonoBehaviour, IMMPersistent { [Header("Save")] /// whether or not this object should be saved [Tooltip("whether or not this object should be saved")] public bool SaveActive = true; [Header("ID")] /// an optional suffix to add to the GUID, to make it more readable [Tooltip("an optional suffix to add to the GUID, to make it more readable")] public string UniqueIDSuffix; /// the object's unique ID [Tooltip("the object's unique ID")] [SerializeField] [MMReadOnly] protected string _guid; /// a debug button used to force a new GUI generation [MMInspectorButton("GenerateGuid")] public bool GenerateGuidButton; /// /// On validate, we make sure the object gets a valid GUID /// protected virtual void OnValidate() { ValidateGuid(); } /// /// Returns the object's GUID /// /// public virtual string GetGuid() => _guid; /// /// Lets you set the object's GUID /// /// public virtual void SetGuid(string newGUID) => _guid = newGUID; /// /// On save, does nothing, meant to be extended /// /// public virtual string OnSave() { return string.Empty; } /// /// On load, does nothing, meant to be extended /// /// public virtual void OnLoad(string data) { } /// /// Lets the persistency manager know whether or not the object should be saved /// /// public virtual bool ShouldBeSaved() { return SaveActive; } /// /// Generates a unique ID for the object, using the scene name, the object name, and a GUID /// /// public virtual string GenerateGuid() { string newGuid = Guid.NewGuid().ToString(); string guid = this.gameObject.scene.name + "-" + this.gameObject.name + "-" + newGuid; if (!string.IsNullOrEmpty(UniqueIDSuffix)) { guid += "-" + UniqueIDSuffix; } this.SetGuid(guid); return guid; } /// /// Checks if the object's ID is unique or not /// /// /// public virtual bool GuidIsUnique(string guid) { return Resources.FindObjectsOfTypeAll().Count(x => x.GetGuid() == guid) == 1; } /// /// Validates the object's GUID, and generates a new one if needed, until a unique one is found /// public virtual void ValidateGuid() { if (!this.gameObject.scene.IsValid()) { _guid = string.Empty; return; } int maxCount = 1000; int i = 0; while ( (string.IsNullOrEmpty(_guid) || !GuidIsUnique(_guid) ) && (i < maxCount) ) { GenerateGuid(); i++; } if (i == maxCount) { Debug.LogWarning(this.gameObject.name + " couldn't generate a unique GUID after " + maxCount + " tries, you should probably change its UniqueIDSuffix"); } } } }