
Hello i’d like to automatically assign a random id, when I create a scriptable object. I do not want this ID to change during run time/


Hello i’d like to automatically assign a random id, when I create a scriptable object. I do not want this ID to change during run time/

You can do it in OnValidate(). Put code to check if the I’d is null,band if so, assign a random value.
This is fine, until you duplicate a scene object, or drag instantiate multiple of the same prefab (the prefab will already have a guid) as you will end up with the same guid in multiple objects.
I did come up with a workaround for this which entailed using a custom inspector, but I can’t find it at the moment. I’ll take a another look later and see if I can dig it up.
ty
Sorry it took a while to get back to you, I had to strip out the relevant code from a much larger script.
I hope this helps.
Add this to any game object to give it a persistent guid property. Prefabs aren’t allocated a guid until instantiated in a scene, and duplicated scene objects will automatically be allocated a different guid from the original.
Tested in Unity 2019.3.14f1.
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
public class GuidObject : MonoBehaviour
{
[HideInInspector] public string objID;
}
This goes in an Editor folder
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
[CustomEditor(typeof(GuidObject))]
public class GuidObjInspector : Editor
{
private const string OBJ_KEY_MSG = "Object Guid will be set on instance when instantiated";
static Dictionary<string, GuidObject> storedSceneObjects;
static Scene currentStoreObjectsScene;
SerializedProperty objIDProp;
bool guiEnabled;
GuidObject guidObject;
private void OnEnable()
{
guidObject = target as GuidObject;
objIDProp = serializedObject.FindProperty("objID");
if (storedSceneObjects == null || currentStoreObjectsScene != EditorSceneManager.GetActiveScene())
{
storedSceneObjects = new Dictionary<string, GuidObject>();
currentStoreObjectsScene = EditorSceneManager.GetActiveScene();
}
AddThisObjectToCollection();
}
public override void OnInspectorGUI()
{
serializedObject.UpdateIfRequiredOrScript();
DoGuidField();
serializedObject.ApplyModifiedProperties();
}
private void DoGuidField()
{
GUI.enabled = false;
EditorGUILayout.PropertyField(objIDProp);
GUI.enabled = guiEnabled;
if (!IsPrefabAsset())
{
if (string.IsNullOrEmpty(objIDProp.stringValue) || objIDProp.stringValue == OBJ_KEY_MSG) objIDProp.stringValue = System.Guid.NewGuid().ToString();
}
else if (IsPrefabAsset())
{
objIDProp.stringValue = "";
EditorGUILayout.HelpBox(OBJ_KEY_MSG, MessageType.Warning);
}
}
/// <summary>
/// Returns false if the selected object isn't part of a prefab or is an instance of a prefab in a scene.
/// </summary>
/// <returns></returns>
private bool IsPrefabAsset()
{
var prefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetPrefabStage(guidObject.gameObject);
return !(!PrefabUtility.IsPartOfPrefabAsset(guidObject.gameObject) && prefabStage == null);
}
private void AddThisObjectToCollection()
{
if (!IsPrefabAsset())
{
if (!storedSceneObjects.ContainsKey(objIDProp.stringValue))
{
storedSceneObjects.Add(objIDProp.stringValue, guidObject);
}
else
{
if (storedSceneObjects[objIDProp.stringValue] != guidObject)
{
Debug.Log("Found same Guid on different scene objects, fixing...");
objIDProp.stringValue = System.Guid.NewGuid().ToString();
serializedObject.ApplyModifiedPropertiesWithoutUndo();
storedSceneObjects.Add(guidObject.objID, guidObject);
}
}
}
}
}