using UnityEngine; using UnityEditor; using Unity.Mathematics; using System; using System.Reflection; using System.Collections; namespace NanoBrain { [CustomPropertyDrawer(typeof(Neuron))] class NeuronDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // Draw foldout + properties label = EditorGUI.BeginProperty(position, label, property); // Begin indent block int indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; object instance = GetTargetObjectOfProperty(property); float lineHeight = EditorGUIUtility.singleLineHeight; Rect r = new(position.x, position.y, position.width, lineHeight); if (instance != null) { FieldInfo field = typeof(Neuron).GetField("_outputValue", BindingFlags.NonPublic | BindingFlags.Instance); if (field != null) { float3 val = (float3)field.GetValue(instance); EditorGUI.Vector3Field(r, $"Neuron: {label}", val); } } EditorGUI.indentLevel = indent; EditorGUI.EndProperty(); } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { // height for 1 line return (EditorGUIUtility.singleLineHeight * 1) + (EditorGUIUtility.standardVerticalSpacing * 0); } public static object GetTargetObjectOfProperty(SerializedProperty prop) { var path = prop.propertyPath.Replace(".Array.data[", "["); object obj = prop.serializedObject.targetObject; var elements = path.Split('.'); foreach (var element in elements) { if (element.Contains("[")) { var elementName = element.Substring(0, element.IndexOf("[")); var index = Convert.ToInt32(element.Substring(element.IndexOf("[")).Replace("[", "").Replace("]", "")); obj = GetValue_Imp(obj, elementName, index); } else { obj = GetValue_Imp(obj, element); } } return obj; } static object GetValue_Imp(object source, string name) { if (source == null) return null; Type t = source.GetType(); FieldInfo f = t.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (f != null) return f.GetValue(source); PropertyInfo p = t.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); return p?.GetValue(source, null); } static object GetValue_Imp(object source, string name, int index) { if (GetValue_Imp(source, name) is not IEnumerable enumerable) return null; IEnumerator en = enumerable.GetEnumerator(); for (int i = 0; i <= index; i++) { if (!en.MoveNext()) return null; } return en.Current; } } }