1
+ #if UNITY_2020_1_OR_NEWER
2
+ using UnityEditor ;
3
+ using UnityEngine ;
4
+ using UnityEngine . Events ;
5
+ using System . Reflection ;
6
+ using UnityEditorInternal ;
7
+
8
+ namespace Lachee . Utilities . Editor
9
+ {
10
+ [ CustomPropertyDrawer ( typeof ( UnityEventBase ) , true ) ]
11
+ public class UnityEventDrawer : UnityEditorInternal . UnityEventDrawer
12
+ {
13
+ #region Private Functions i steal from UnityEventDrawerer
14
+ private static readonly FieldInfo fi_reoderableList ;
15
+ private static readonly FieldInfo fi_dummyEvent ;
16
+ private static readonly FieldInfo fi_text ;
17
+ private static readonly MethodInfo mi_RestoreState ;
18
+ private static readonly MethodInfo mi_GetDummyEvent ;
19
+
20
+ static UnityEventDrawer ( )
21
+ {
22
+ var T = typeof ( UnityEditorInternal . UnityEventDrawer ) ;
23
+ fi_reoderableList = T . GetField ( "m_ReorderableList" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
24
+ fi_dummyEvent = T . GetField ( "m_DummyEvent" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
25
+ fi_text = T . GetField ( "m_Text" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
26
+ mi_GetDummyEvent = T . GetMethod ( "GetDummyEvent" , BindingFlags . NonPublic | BindingFlags . Static ) ;
27
+ mi_RestoreState = T . GetMethod ( "RestoreState" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
28
+ }
29
+
30
+ private static UnityEventBase GetDummyEvent ( SerializedProperty prop )
31
+ => ( UnityEventBase ) mi_GetDummyEvent . Invoke ( null , new object [ ] { prop } ) ;
32
+
33
+ private ReorderableList reorderableList
34
+ {
35
+ get => ( ReorderableList ) fi_reoderableList . GetValue ( this ) ;
36
+ }
37
+ private UnityEventBase dummyEvent
38
+ {
39
+ get => ( UnityEventBase ) fi_dummyEvent . GetValue ( this ) ;
40
+ set => fi_dummyEvent . SetValue ( this , value ) ;
41
+ }
42
+ private string text
43
+ {
44
+ get => ( string ) fi_text . GetValue ( this ) ;
45
+ set => fi_text . SetValue ( this , value ) ;
46
+ }
47
+ private State RestoreState ( SerializedProperty property )
48
+ => ( State ) mi_RestoreState . Invoke ( this , new [ ] { property } ) ;
49
+ #endregion
50
+
51
+ private readonly GUIContent iconToolbarPlus = EditorGUIUtility . TrIconContent ( "Toolbar Plus" , "Add new event listener" ) ;
52
+ private readonly GUIStyle headerBackground = "LODSliderBG" ;
53
+ private readonly GUIStyle preButton = "RL FooterButton" ;
54
+ private readonly Color headerColor = new Color ( 0.85f , 0.85f , 0.85f ) ;
55
+
56
+ private bool ? _isFolded ;
57
+ private bool isFolded
58
+ {
59
+ get => _isFolded . GetValueOrDefault ( EditorPrefs . GetBool ( $ "com.lachee.utilities.UnityEventsFoldout", true ) ) ;
60
+ set
61
+ {
62
+ _isFolded = value ;
63
+ EditorPrefs . SetBool ( $ "com.lachee.utilities.UnityEventsFoldout", value ) ;
64
+ }
65
+ }
66
+
67
+ private float CalculateBackgroundHeight ( SerializedProperty property )
68
+ {
69
+ var list = reorderableList ;
70
+ if ( list == null || list . count == 0 || isFolded )
71
+ return EditorGUIUtility . singleLineHeight + 2f ;
72
+
73
+ return base . GetPropertyHeight ( property , GUIContent . none ) ;
74
+ }
75
+
76
+ public override void OnGUI ( Rect position , SerializedProperty property , GUIContent label )
77
+ {
78
+ RestoreState ( property ) ;
79
+
80
+ text = label . text ;
81
+ dummyEvent = GetDummyEvent ( property ) ;
82
+
83
+ float lineHeight = EditorGUIUtility . singleLineHeight ;
84
+
85
+ // Draw the folder
86
+ if ( reorderableList . count > 0 )
87
+ {
88
+ isFolded = ! EditorGUI . Foldout ( new Rect ( position . x , position . y , position . width , lineHeight ) , ! isFolded , GUIContent . none ) ;
89
+ }
90
+ else
91
+ {
92
+ _isFolded = true ;
93
+ }
94
+
95
+ // Draw the event box
96
+ Rect headerRect = new Rect ( position . x + 2 , position . y , position . width - 2 , CalculateBackgroundHeight ( property ) ) ;
97
+ Rect headerLabel = new Rect ( headerRect . x + 6 , headerRect . y + 1 , headerRect . width - 100 , lineHeight ) ;
98
+ Rect headerAddButton = new Rect ( headerRect . x + headerRect . width - 25 , headerRect . y + 2 , 24 , headerRect . height + 4 ) ;
99
+
100
+ // Draw the base GUI if we are unfolded
101
+ if ( ! isFolded )
102
+ {
103
+ base . OnGUI ( headerRect , property , label ) ;
104
+ }
105
+ else
106
+ {
107
+ if ( Event . current . type == EventType . Repaint )
108
+ {
109
+ GUI . backgroundColor = headerColor ;
110
+ headerBackground . Draw ( headerRect , GUIContent . none , false , false , false , false ) ;
111
+ GUI . backgroundColor = Color . white ;
112
+ }
113
+
114
+ DrawEventHeader ( headerLabel ) ;
115
+ if ( GUI . Button ( headerAddButton , iconToolbarPlus , preButton ) )
116
+ {
117
+ isFolded = false ;
118
+ OnAddEvent ( reorderableList ) ;
119
+ }
120
+ }
121
+ }
122
+
123
+ public override float GetPropertyHeight ( SerializedProperty property , GUIContent label )
124
+ {
125
+ return CalculateBackgroundHeight ( property ) + 5f ;
126
+ }
127
+
128
+ }
129
+ }
130
+ #endif
0 commit comments