com.soosvet_games.common_tools 1.1.6 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,7 @@
1
- using UnityEditor;
1
+ using System;
2
+ using System.Linq.Expressions;
3
+ using System.Reflection;
4
+ using UnityEditor;
2
5
  using UnityEngine;
3
6
 
4
7
  namespace SoosvetGames.CommonTools.Extensions.Editor
@@ -6,43 +9,150 @@ namespace SoosvetGames.CommonTools.Extensions.Editor
6
9
  [ InitializeOnLoad ]
7
10
  internal static class HierarchyActivationTool
8
11
  {
12
+ private static FieldInfo _callbackField;
13
+ private static Delegate _callback;
14
+
9
15
  static HierarchyActivationTool()
10
16
  {
11
- #if UNITY_6000_5_OR_NEWER
12
- EditorApplication.hierarchyWindowItemByEntityIdOnGUI -= HierarchyWindowOnGui;
13
- EditorApplication.hierarchyWindowItemByEntityIdOnGUI += HierarchyWindowOnGui;
14
- #else
15
- EditorApplication.hierarchyWindowItemOnGUI -= HierarchyWindowOnGui;
16
- EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowOnGui;
17
- #endif
18
- }
17
+ Install();
19
18
 
20
- #if UNITY_6000_5_OR_NEWER
19
+ AssemblyReloadEvents.beforeAssemblyReload += Uninstall;
20
+ }
21
21
 
22
- private static void HierarchyWindowOnGui(EntityId entityId, Rect selectionRect)
22
+ private static void Install()
23
23
  {
24
- var obj = EditorUtility.EntityIdToObject(entityId) as GameObject;
24
+ const BindingFlags flags = BindingFlags.Public | BindingFlags.Static;
25
25
 
26
- DrawToggle(obj, selectionRect);
27
- }
26
+ // Unity 6.5 / 6.6+
27
+ _callbackField = typeof(EditorApplication).GetField( "hierarchyWindowItemByEntityIdOnGUI", flags );
28
+
29
+ // Старые версии Unity
30
+ if ( _callbackField == null )
31
+ {
32
+ _callbackField = typeof(EditorApplication).GetField( "hierarchyWindowItemOnGUI", flags );
33
+ }
34
+
35
+ if ( _callbackField == null )
36
+ {
37
+ Debug.LogWarning( "[HierarchyActivationTool] " + "Hierarchy callback was not found." );
38
+
39
+ return;
40
+ }
41
+
42
+ Type delegateType = _callbackField.FieldType;
43
+
44
+ MethodInfo invokeMethod = delegateType.GetMethod( "Invoke" );
45
+
46
+ if ( invokeMethod == null )
47
+ return;
48
+
49
+ ParameterInfo[] parameters = invokeMethod.GetParameters();
50
+
51
+ if ( parameters.Length != 2 )
52
+ return;
53
+
54
+ Type idType = parameters[ 0 ].ParameterType;
55
+ Type rectType = parameters[ 1 ].ParameterType;
56
+
57
+ if ( rectType != typeof(Rect) )
58
+ return;
59
+
60
+ // В новой Unity это EntityIdToObject(EntityId).
61
+ // В старой — InstanceIDToObject(int).
62
+ string converterName = idType == typeof(int) ? "InstanceIDToObject" : "EntityIdToObject";
63
+
64
+ MethodInfo converterMethod = FindConverterMethod( converterName, idType );
65
+
66
+ if ( converterMethod == null )
67
+ {
68
+ Debug.LogWarning( $"[HierarchyActivationTool] " + $"{converterName} was not found." );
69
+
70
+ return;
71
+ }
72
+
73
+ /*
74
+ * Здесь динамически создаётся callback правильного типа:
75
+ *
76
+ * Старые Unity:
77
+ * (int instanceId, Rect rect)
78
+ *
79
+ * Новые Unity:
80
+ * (EntityId entityId, Rect rect)
81
+ *
82
+ * Поэтому EntityId вообще не фигурирует в исходном коде
83
+ * и старые Unity тоже могут его скомпилировать.
84
+ */
28
85
 
29
- #else
86
+ ParameterExpression idParameter = Expression.Parameter( idType, "id" );
30
87
 
31
- private static void HierarchyWindowOnGui( int instanceId, Rect selectionRect )
88
+ ParameterExpression rectParameter = Expression.Parameter( typeof(Rect), "selectionRect" );
89
+
90
+ MethodCallExpression objectCall = Expression.Call( converterMethod, idParameter );
91
+
92
+ UnaryExpression gameObject = Expression.TypeAs( objectCall, typeof(GameObject) );
93
+
94
+ MethodInfo drawMethod = typeof(HierarchyActivationTool).GetMethod( nameof(DrawToggle), BindingFlags.NonPublic | BindingFlags.Static );
95
+
96
+ MethodCallExpression drawCall = Expression.Call( drawMethod, gameObject, rectParameter );
97
+
98
+ _callback = Expression.Lambda( delegateType, drawCall, idParameter, rectParameter ).Compile();
99
+
100
+ Delegate currentCallback = _callbackField.GetValue( null ) as Delegate;
101
+
102
+ Delegate newCallback = Delegate.Combine( currentCallback, _callback );
103
+
104
+ _callbackField.SetValue( null, newCallback );
105
+ }
106
+
107
+ private static MethodInfo FindConverterMethod( string methodName, Type idType )
32
108
  {
33
- var obj = Resources.InstanceIDToObject( instanceId ) as GameObject;
109
+ const BindingFlags flags = BindingFlags.Public | BindingFlags.Static;
110
+
111
+ MethodInfo[] methods = typeof(EditorUtility).GetMethods( flags );
112
+
113
+ foreach ( MethodInfo method in methods )
114
+ {
115
+ if ( method.Name != methodName )
116
+ continue;
34
117
 
35
- DrawToggle( obj, selectionRect );
118
+ ParameterInfo[] parameters = method.GetParameters();
119
+
120
+ if ( parameters.Length != 1 )
121
+ continue;
122
+
123
+ if ( parameters[ 0 ].ParameterType != idType )
124
+ continue;
125
+
126
+ return method;
127
+ }
128
+
129
+ return null;
36
130
  }
37
131
 
38
- #endif
132
+ private static void Uninstall()
133
+ {
134
+ if ( _callbackField == null || _callback == null )
135
+ {
136
+ return;
137
+ }
138
+
139
+ Delegate currentCallback = _callbackField.GetValue( null ) as Delegate;
140
+
141
+ Delegate newCallback = Delegate.Remove( currentCallback, _callback );
142
+
143
+ _callbackField.SetValue( null, newCallback );
144
+
145
+ _callback = null;
146
+ }
39
147
 
40
148
  private static void DrawToggle( GameObject obj, Rect selectionRect )
41
149
  {
42
150
  if ( obj == null )
43
151
  return;
44
152
 
45
- var rect = new Rect( selectionRect ) { x = 35, width = 18 };
153
+ // Сохраняем расположение как в твоём
154
+ // оригинальном инструменте.
155
+ Rect rect = new Rect( selectionRect ) { x = 35, width = 18 };
46
156
 
47
157
  bool previousValue = obj.activeSelf;
48
158
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name" : "com.soosvet_games.common_tools",
3
3
  "displayName" : "Soosvet Games Common Tools",
4
- "version" : "1.1.6",
4
+ "version" : "1.1.8",
5
5
  "author" : "Soosvet Games",
6
6
  "description" : "Common tools for Unity.",
7
7
  "repository": {