using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace NanoBrain.Unity { [CustomPropertyDrawer(typeof(ClusterJson))] class ClusterJson_Drawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); ClusterJson clusterJson = property.objectReferenceValue as ClusterJson; if (clusterJson == null) { clusterJson = ScriptableObject.CreateInstance(); property.objectReferenceValue = clusterJson; property.serializedObject.ApplyModifiedProperties(); EditorUtility.SetDirty(property.serializedObject.targetObject); } SerializedObject so = new(clusterJson); SerializedProperty jsonFileProp = so.FindProperty(nameof(ClusterJson.jsonFile)); EditorGUI.BeginChangeCheck(); TextAsset current = jsonFileProp.objectReferenceValue as TextAsset; Rect fieldRect = new(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight); TextAsset newAsset = (TextAsset)EditorGUI.ObjectField(fieldRect, label, current, typeof(TextAsset), false); if (EditorGUI.EndChangeCheck()) { jsonFileProp.objectReferenceValue = newAsset; so.ApplyModifiedProperties(); } bool showWarning = IsInvalidJson(jsonFileProp); if (showWarning) { Rect helpRect = new( position.x, position.y + EditorGUIUtility.singleLineHeight + 2f, position.width, EditorGUIUtility.singleLineHeight * 2f ); propertyExtraHeight = 2 + 2 * EditorGUIUtility.singleLineHeight; EditorGUI.HelpBox(helpRect, "Selected asset is not a .json file.", MessageType.Error); } else propertyExtraHeight = 0; EditorGUI.EndProperty(); } private float propertyExtraHeight = 0; public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return EditorGUIUtility.singleLineHeight + propertyExtraHeight; } private readonly Dictionary _invalidCache = new(); private bool IsInvalidJson(SerializedProperty jsonFileProp) { TextAsset current = jsonFileProp.objectReferenceValue as TextAsset; if (current == null) return false; EntityId id = current.GetEntityId(); if (_invalidCache.TryGetValue(id, out bool invalid)) return invalid; string path = AssetDatabase.GetAssetPath(current); invalid = !path.EndsWith(".json", System.StringComparison.OrdinalIgnoreCase); _invalidCache[id] = invalid; return invalid; } } }