We need an identification number (ID) to connect a GameObject (entity) to a database or differentiate GameObjects with the same name.
But the ID provided by Unity though is unique for each GameObject changes every session. That is, it can not be used to create a database of the game, or differentiate GameObjects with the same name in different sessions.
I created a class called UniqueID that generates and stores a unique and constant ID, saving the last ID generated by PlayerPrefs a file or a binary file.
PlayerPrefs using to store the last ID generated:
:
using UnityEngine;
[System.Serializable]
public class UniqueID{
public int ID;
static string key = "UniqueID";
public UniqueID(){
if(PlayerPrefs.HasKey("UniqueID")){
this.ID = PlayerPrefs.GetInt(key);
PlayerPrefs.SetInt(key,this.ID+1);
return;
}
PlayerPrefs.SetInt(key,1);
this.ID = 0;
}
public static implicit operator int(UniqueID uniqueID){ return uniqueID.ID; }
public static implicit operator string(UniqueID uniqueID) { return uniqueID.ID.ToString(); }
}
Using BinaryWriter, It is easier to restart identifiers to 0. You just need to remove the UniqueID file.
using UnityEngine;
using System.IO;
[System.Serializable]
public class UniqueID{
public int ID;
static string path = "C:/UniqueID";
public UniqueID(){
if(File.Exists(path)){
BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open));
this.ID = reader.Read();
reader.Close();
BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Open));
writer.Write(this.ID+1);
writer.Close();
return;
}
BinaryWriter _writer = new BinaryWriter(File.Open(path, FileMode.Create));
_writer.Write(1);
_writer.Close();
this.ID = 0;
}
public static implicit operator int(UniqueID uniqueID){ return uniqueID.ID; }
public static implicit operator string(UniqueID uniqueID) { return uniqueID.ID.ToString(); }
}
Also, I created a CustomDrawer for UniqueID class. Only read ID property:
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer (typeof (UniqueID))]
public class UniqueIDDrawer : PropertyDrawer {
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
EditorGUI.BeginProperty (position, label, property);
position = EditorGUI.PrefixLabel (position, GUIUtility.GetControlID (FocusType.Passive), label);
int indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
string value = property.FindPropertyRelative ("ID").intValue.ToString();
Rect IDRect = new Rect (position.x, position.y, 25f + value.Length * 6f, position.height+2f);
EditorGUI.LabelField(IDRect,value,GUI.skin.box);
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty ();
}
}
How to use:
using UnityEngine;
public class script : MonoBehaviour {
public UniqueID ID;
void Start(){
Debug.Log(this.gameObject.name + " UniqueID: " + this.ID);
}
}