A game about forced loneliness, made by TACStudios
1using System; 2using System.Collections.Generic; 3using System.Collections.ObjectModel; 4using UnityEditor; 5using UnityEngine; 6 7namespace Unity.Mathematics.Editor 8{ 9 [CustomPropertyDrawer(typeof(bool2x2)), CustomPropertyDrawer(typeof(bool2x3)), CustomPropertyDrawer(typeof(bool2x4))] 10 [CustomPropertyDrawer(typeof(bool3x2)), CustomPropertyDrawer(typeof(bool3x3)), CustomPropertyDrawer(typeof(bool3x4))] 11 [CustomPropertyDrawer(typeof(bool4x2)), CustomPropertyDrawer(typeof(bool4x3)), CustomPropertyDrawer(typeof(bool4x4))] 12 [CustomPropertyDrawer(typeof(double2x2)), CustomPropertyDrawer(typeof(double2x3)), CustomPropertyDrawer(typeof(double2x4))] 13 [CustomPropertyDrawer(typeof(double3x2)), CustomPropertyDrawer(typeof(double3x3)), CustomPropertyDrawer(typeof(double3x4))] 14 [CustomPropertyDrawer(typeof(double4x2)), CustomPropertyDrawer(typeof(double4x3)), CustomPropertyDrawer(typeof(double4x4))] 15 [CustomPropertyDrawer(typeof(float2x2)), CustomPropertyDrawer(typeof(float2x3)), CustomPropertyDrawer(typeof(float2x4))] 16 [CustomPropertyDrawer(typeof(float3x2)), CustomPropertyDrawer(typeof(float3x3)), CustomPropertyDrawer(typeof(float3x4))] 17 [CustomPropertyDrawer(typeof(float4x2)), CustomPropertyDrawer(typeof(float4x3)), CustomPropertyDrawer(typeof(float4x4))] 18 [CustomPropertyDrawer(typeof(int2x2)), CustomPropertyDrawer(typeof(int2x3)), CustomPropertyDrawer(typeof(int2x4))] 19 [CustomPropertyDrawer(typeof(int3x2)), CustomPropertyDrawer(typeof(int3x3)), CustomPropertyDrawer(typeof(int3x4))] 20 [CustomPropertyDrawer(typeof(int4x2)), CustomPropertyDrawer(typeof(int4x3)), CustomPropertyDrawer(typeof(int4x4))] 21 [CustomPropertyDrawer(typeof(uint2x2)), CustomPropertyDrawer(typeof(uint2x3)), CustomPropertyDrawer(typeof(uint2x4))] 22 [CustomPropertyDrawer(typeof(uint3x2)), CustomPropertyDrawer(typeof(uint3x3)), CustomPropertyDrawer(typeof(uint3x4))] 23 [CustomPropertyDrawer(typeof(uint4x2)), CustomPropertyDrawer(typeof(uint4x3)), CustomPropertyDrawer(typeof(uint4x4))] 24 class MatrixDrawer : PropertyDrawer 25 { 26#if !UNITY_2023_2_OR_NEWER 27 public override bool CanCacheInspectorGUI(SerializedProperty property) 28 { 29 return false; 30 } 31#endif 32 33 public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 34 { 35 if (!property.isExpanded) 36 return EditorGUIUtility.singleLineHeight; 37 var rows = 1 + property.type[property.type.Length - 3] - '0'; 38 return rows * EditorGUIUtility.singleLineHeight + (rows - 1) * EditorGUIUtility.standardVerticalSpacing; 39 } 40 41 static ReadOnlyCollection<string> k_ColPropertyPaths = 42 new ReadOnlyCollection<string>(new[] { "c0", "c1", "c2", "c3" }); 43 static ReadOnlyCollection<string> k_RowPropertyPaths = 44 new ReadOnlyCollection<string>(new[] { "x", "y", "z", "w" }); 45 46 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 47 { 48 position.height = EditorGUIUtility.singleLineHeight; 49 EditorGUI.PropertyField(position, property, label, false); 50 51 if (Event.current.type == EventType.ContextClick && position.Contains(Event.current.mousePosition)) 52 { 53 DoUtilityMenu(property); 54 Event.current.Use(); 55 } 56 57 if (!property.isExpanded) 58 return; 59 60 var rows = property.type[property.type.Length - 3] - '0'; 61 var cols = property.type[property.type.Length - 1] - '0'; 62 63 ++EditorGUI.indentLevel; 64 position = EditorGUI.IndentedRect(position); 65 --EditorGUI.indentLevel; 66 67 var elementType = property.FindPropertyRelative("c0.x").propertyType; 68 for (var row = 0; row < rows; ++row) 69 { 70 position.y += position.height + EditorGUIUtility.standardVerticalSpacing; 71 var elementRect = new Rect(position) 72 { 73 width = elementType == SerializedPropertyType.Boolean 74 ? EditorGUIUtility.singleLineHeight 75 : (position.width - (cols - 1) * EditorGUIUtility.standardVerticalSpacing) / cols 76 }; 77 for (var col = 0; col < cols; ++col) 78 { 79 EditorGUI.PropertyField( 80 elementRect, 81 property.FindPropertyRelative($"{k_ColPropertyPaths[col]}.{k_RowPropertyPaths[row]}"), 82 GUIContent.none 83 ); 84 elementRect.x += elementRect.width + EditorGUIUtility.standardVerticalSpacing; 85 } 86 } 87 } 88 89 Dictionary<SerializedPropertyType, Action<SerializedProperty, bool>> k_UtilityValueSetters = 90 new Dictionary<SerializedPropertyType, Action<SerializedProperty, bool>> 91 { 92 { SerializedPropertyType.Boolean, (property, b) => property.boolValue = b }, 93 { SerializedPropertyType.Float, (property, b) => property.floatValue = b ? 1f : 0f }, 94 { SerializedPropertyType.Integer, (property, b) => property.intValue = b ? 1 : 0 } 95 }; 96 97 void DoUtilityMenu(SerializedProperty property) 98 { 99 var rows = property.type[property.type.Length - 3] - '0'; 100 var cols = property.type[property.type.Length - 1] - '0'; 101 var elementType = property.FindPropertyRelative("c0.x").propertyType; 102 var setValue = k_UtilityValueSetters[elementType]; 103 var menu = new GenericMenu(); 104 property = property.Copy(); 105 menu.AddItem( 106 EditorGUIUtility.TrTextContent("Set to Zero"), 107 false, 108 () => 109 { 110 property.serializedObject.Update();; 111 for (var row = 0; row < rows; ++row) 112 for (var col = 0; col < cols; ++col) 113 setValue( 114 property.FindPropertyRelative($"{k_ColPropertyPaths[col]}.{k_RowPropertyPaths[row]}"), 115 false 116 ); 117 property.serializedObject.ApplyModifiedProperties(); 118 } 119 ); 120 if (rows == cols) 121 { 122 menu.AddItem( 123 EditorGUIUtility.TrTextContent("Reset to Identity"), 124 false, 125 () => 126 { 127 property.serializedObject.Update(); 128 for (var row = 0; row < rows; ++row) 129 for (var col = 0; col < cols; ++col) 130 setValue( 131 property.FindPropertyRelative($"{k_ColPropertyPaths[col]}.{k_RowPropertyPaths[row]}"), 132 row == col 133 ); 134 property.serializedObject.ApplyModifiedProperties(); 135 } 136 ); 137 } 138 menu.ShowAsContext(); 139 } 140 } 141}