Created
October 25, 2023 08:39
-
-
Save GeorgiyRyaposov/3e0d89eaafe2e454cb71e1fed1fef8c3 to your computer and use it in GitHub Desktop.
Generate unique id for scriptable + duplicate check
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
public class ScriptableObjectIdAttribute : PropertyAttribute { } | |
#if UNITY_EDITOR | |
[UnityEditor.CustomPropertyDrawer(typeof(ScriptableObjectIdAttribute))] | |
public class ScriptableObjectIdDrawer : UnityEditor.PropertyDrawer | |
{ | |
private const string CHECKED_SCRIPTABLE_DUPLICATE_KEY = "CheckedScriptableDuplicate"; | |
public override void OnGUI(Rect position, UnityEditor.SerializedProperty property, GUIContent label) | |
{ | |
GUI.enabled = false; | |
if (string.IsNullOrEmpty(property.stringValue) || | |
(!IsDuplicateChecked(property) && HasDuplicateId(property))) | |
{ | |
if (!UnityEditor.AssetDatabase.TryGetGUIDAndLocalFileIdentifier(property.serializedObject.targetObject, out var guid, | |
out long _)) | |
{ | |
property.stringValue = guid; | |
} | |
else | |
{ | |
property.stringValue = Guid.NewGuid().ToString(); | |
} | |
} | |
UnityEditor.EditorGUI.PropertyField(position, property, label, true); | |
GUI.enabled = true; | |
} | |
//Check other instances ID, if any has same id | |
//in case when scriptable was duplicated | |
private bool HasDuplicateId(UnityEditor.SerializedProperty property) | |
{ | |
var id = property.stringValue; | |
var duplicates = 0; | |
var type = property.serializedObject.targetObject.GetType(); | |
var otherObjects = Resources.FindObjectsOfTypeAll(type); | |
foreach (var obj in otherObjects) | |
{ | |
if (obj is not ScriptableObject) | |
{ | |
continue; | |
} | |
var serializedObj = new UnityEditor.SerializedObject(obj); | |
var duplicateProperty = serializedObj.FindProperty(property.name); | |
if (duplicateProperty == null) | |
{ | |
continue; | |
} | |
if (string.Equals(duplicateProperty.stringValue, id, StringComparison.Ordinal)) | |
{ | |
duplicates++; | |
if (duplicates > 1) | |
{ | |
return true; | |
} | |
} | |
} | |
SetDuplicateAsChecked(property); | |
return false; | |
} | |
private static bool IsDuplicateChecked(UnityEditor.SerializedProperty serializedProperty) | |
{ | |
var checkedName = UnityEditor.EditorPrefs.GetString(CHECKED_SCRIPTABLE_DUPLICATE_KEY, string.Empty); | |
return string.Equals(serializedProperty.serializedObject.targetObject.name, checkedName, StringComparison.Ordinal); | |
} | |
private static void SetDuplicateAsChecked(UnityEditor.SerializedProperty serializedProperty) | |
{ | |
UnityEditor.EditorPrefs.SetString(CHECKED_SCRIPTABLE_DUPLICATE_KEY, serializedProperty.serializedObject.targetObject.name); | |
} | |
} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void OnValidate() | |
{ | |
if (string.IsNullOrEmpty(id)) | |
{ | |
if (UnityEditor.AssetDatabase.TryGetGUIDAndLocalFileIdentifier(this, | |
out var guid, | |
out long _)) | |
{ | |
id = guid; | |
EditorUtility.SetDirty(this); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment