Maybe I’m not understanding how Serialization works, but I’ve been trying to serialize a Guid.
I KNOW that built-in guids are not serializable, so I first tried [SerializeField] string m_guid = System.Guid.NewGuid().ToString();
I was under the assumption that once a serialized field was set to the initial value once, it was stored by Unity, and not filled again unless done so manually.
But it’s generating a new guid every time the project is closed and reopened, and whenever the scripts recompile.
So I tried using code for a serializable Guid I found when searching, but it seems to do the same thing whenever the project is reloaded/recompiled
(The code I tried, for reference, from this post)
using System;
using UnityEngine;
/// <summary>
/// Serializable wrapper for System.Guid.
/// Can be implicitly converted to/from System.Guid.
///
/// Author: Searous
/// </summary>
[Serializable]
public struct SerializableGuid : ISerializationCallbackReceiver {
private Guid guid;
[SerializeField] private string serializedGuid;
public SerializableGuid(Guid guid) {
this.guid = guid;
serializedGuid = null;
}
public override bool Equals(object obj) {
return obj is SerializableGuid guid &&
this.guid.Equals(guid.guid);
}
public override int GetHashCode() {
return -1324198676 + guid.GetHashCode();
}
public void OnAfterDeserialize() {
try {
guid = Guid.Parse(serializedGuid);
} catch {
guid = Guid.Empty;
Debug.LogWarning($"Attempted to parse invalid GUID string '{serializedGuid}'. GUID will set to System.Guid.Empty");
}
}
public void OnBeforeSerialize() {
serializedGuid = guid.ToString();
}
public override string ToString() => guid.ToString();
public static bool operator ==(SerializableGuid a, SerializableGuid b) => a.guid == b.guid;
public static bool operator !=(SerializableGuid a, SerializableGuid b) => a.guid != b.guid;
public static implicit operator SerializableGuid(Guid guid) => new SerializableGuid(guid);
public static implicit operator Guid(SerializableGuid serializable) => serializable.guid;
public static implicit operator SerializableGuid(string serializedGuid) => new SerializableGuid(Guid.Parse(serializedGuid));
public static implicit operator string(SerializableGuid serializedGuid) => serializedGuid.ToString();
}
I tried looking around some more, but still couldn’t understand what seems to be causing me so much headache. I’d be fine just saving the Guid as a string, since I’m not worried about string comparation performance for this use case. (I also heard that maybe ISerializationCallbackReceiver doesn’t work for structs, so I tried making it a class instead, but still no bueno.)
Is there something I’m not understanding about serialization?
Also, it’s important that it be automatically generated when the object is added to the scene, which is why I didn’t just write a property drawer with a button to generate the ID. That would probably work, since the only time Guid.NewGuid would be call is from that button, but it’s REALLY not how I want to do this.
Edit:
OH, I forgot to mention, I did write a bit of code that seemed to actually work, but it felt very hack-y and have no idea if/what errors it would cause for me in the future…
public string ID {
get {
if (string.IsNullOrEmpty(m_ID)) {
m_ID = System.Guid.NewGuid().ToString();
#if UNITY_EDITOR
EditorUtility.SetDirty(this);
#endif
}
return m_ID;
}
}


