com.wallstop-studios.unity-helpers 2.0.0-rc77.7 → 2.0.0-rc77.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.
- package/Editor/Sprites/AnimationViewerWindow.cs +2 -1
- package/Editor/Tools/ImageBlurTool.cs +409 -0
- package/Editor/Tools/ImageBlurTool.cs.meta +3 -0
- package/Editor/Tools.meta +3 -0
- package/Editor/Visuals/EnhancedImageEditor.cs +131 -0
- package/Editor/Visuals/EnhancedImageEditor.cs.meta +11 -0
- package/Editor/Visuals.meta +3 -0
- package/Runtime/Visuals/AnimatedSpriteLayer.cs +130 -0
- package/Runtime/Visuals/AnimatedSpriteLayer.cs.meta +3 -0
- package/Runtime/Visuals/UGUI/EnhancedImage.cs +76 -0
- package/Runtime/Visuals/UGUI/EnhancedImage.cs.meta +3 -0
- package/Runtime/Visuals/UGUI.meta +3 -0
- package/Runtime/{UI → Visuals/UIToolkit}/LayeredImage.cs +4 -126
- package/Runtime/{UI → Visuals/UIToolkit}/MultiFileSelectorElement.cs +3 -3
- package/Runtime/Visuals/UIToolkit.meta +3 -0
- package/Shaders/Materials/BackgroundMask-Material.mat +59 -0
- package/Shaders/Materials/BackgroundMask-Material.mat.meta +8 -0
- package/Shaders/Materials.meta +8 -0
- package/Shaders/ShaderGraph/BackgroundMask.shadergraph +1653 -0
- package/Shaders/ShaderGraph/BackgroundMask.shadergraph.meta +10 -0
- package/Shaders/ShaderGraph.meta +8 -0
- package/Shaders.meta +8 -0
- package/URP/VolumeProfiles/Post Processing Bloom Profile(URP).asset +63 -0
- package/URP/VolumeProfiles/Post Processing Bloom Profile(URP).asset.meta +8 -0
- package/URP/VolumeProfiles.meta +8 -0
- package/URP.meta +8 -0
- package/package.json +2 -1
- /package/Runtime/{UI → Visuals/UIToolkit}/LayeredImage.cs.meta +0 -0
- /package/Runtime/{UI → Visuals/UIToolkit}/MultiFileSelectorElement.cs.meta +0 -0
- /package/Runtime/{UI.meta → Visuals.meta} +0 -0
|
@@ -12,7 +12,8 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
12
12
|
using UnityEditor.UIElements;
|
|
13
13
|
using UnityEngine;
|
|
14
14
|
using UnityEngine.UIElements;
|
|
15
|
-
using
|
|
15
|
+
using WallstopStudios.UnityHelpers.Visuals;
|
|
16
|
+
using WallstopStudios.UnityHelpers.Visuals.UIToolkit;
|
|
16
17
|
using Object = UnityEngine.Object;
|
|
17
18
|
|
|
18
19
|
public sealed class AnimationViewerWindow : EditorWindow
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Editor.Tools
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.IO;
|
|
6
|
+
using System.Linq;
|
|
7
|
+
using System.Threading.Tasks;
|
|
8
|
+
using UnityEditor;
|
|
9
|
+
using UnityEngine;
|
|
10
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
11
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
12
|
+
using WallstopStudios.UnityHelpers.Editor.CustomEditors;
|
|
13
|
+
using Object = UnityEngine.Object;
|
|
14
|
+
|
|
15
|
+
public sealed class ImageBlurTool : EditorWindow
|
|
16
|
+
{
|
|
17
|
+
public List<Object> imageSources = new();
|
|
18
|
+
|
|
19
|
+
private readonly List<Texture2D> _orderedTextures = new();
|
|
20
|
+
private readonly List<Texture2D> _manualTextures = new();
|
|
21
|
+
|
|
22
|
+
private int _blurRadius = 1;
|
|
23
|
+
private Vector2 _scrollPosition;
|
|
24
|
+
|
|
25
|
+
private GUIStyle _impactButtonStyle;
|
|
26
|
+
private SerializedObject _serializedObject;
|
|
27
|
+
private SerializedProperty _imageSourcesProperty;
|
|
28
|
+
|
|
29
|
+
private readonly List<Object> _lastSeenImageSources = new();
|
|
30
|
+
|
|
31
|
+
[MenuItem("Tools/Wallstop Studios/Unity Helpers/Image Blur")]
|
|
32
|
+
public static void ShowWindow()
|
|
33
|
+
{
|
|
34
|
+
GetWindow<ImageBlurTool>("Image Blur Tool");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private void OnEnable()
|
|
38
|
+
{
|
|
39
|
+
_serializedObject = new SerializedObject(this);
|
|
40
|
+
_imageSourcesProperty = _serializedObject.FindProperty(nameof(imageSources));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private void OnGUI()
|
|
44
|
+
{
|
|
45
|
+
_serializedObject.Update();
|
|
46
|
+
|
|
47
|
+
_impactButtonStyle ??= new GUIStyle(GUI.skin.button)
|
|
48
|
+
{
|
|
49
|
+
normal = { textColor = Color.yellow },
|
|
50
|
+
fontStyle = FontStyle.Bold,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
EditorGUILayout.LabelField("Image Blur Settings", EditorStyles.boldLabel);
|
|
54
|
+
EditorGUILayout.Space();
|
|
55
|
+
|
|
56
|
+
EditorGUILayout.LabelField("Manual Folder Selection", EditorStyles.boldLabel);
|
|
57
|
+
PersistentDirectoryGUI.PathSelectorObjectArray(
|
|
58
|
+
_imageSourcesProperty,
|
|
59
|
+
nameof(ImageBlurTool)
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (
|
|
63
|
+
_serializedObject.ApplyModifiedProperties()
|
|
64
|
+
|| !_lastSeenImageSources.SequenceEqual(imageSources)
|
|
65
|
+
)
|
|
66
|
+
{
|
|
67
|
+
_lastSeenImageSources.Clear();
|
|
68
|
+
_lastSeenImageSources.AddRange(imageSources);
|
|
69
|
+
_manualTextures.Clear();
|
|
70
|
+
foreach (Object directory in imageSources.Where(Objects.NotNull))
|
|
71
|
+
{
|
|
72
|
+
string path = AssetDatabase.GetAssetPath(directory);
|
|
73
|
+
if (string.IsNullOrWhiteSpace(path))
|
|
74
|
+
{
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
TrySyncDirectory(path, _manualTextures);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
Event evt = Event.current;
|
|
83
|
+
Rect dropArea = GUILayoutUtility.GetRect(0f, 75f, GUILayout.ExpandWidth(true));
|
|
84
|
+
GUI.Box(dropArea, "Drag & Drop Images/Folders Here");
|
|
85
|
+
|
|
86
|
+
switch (evt.type)
|
|
87
|
+
{
|
|
88
|
+
case EventType.DragUpdated:
|
|
89
|
+
case EventType.DragPerform:
|
|
90
|
+
{
|
|
91
|
+
if (!dropArea.Contains(evt.mousePosition))
|
|
92
|
+
{
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
|
97
|
+
|
|
98
|
+
if (evt.type == EventType.DragPerform)
|
|
99
|
+
{
|
|
100
|
+
DragAndDrop.AcceptDrag();
|
|
101
|
+
foreach (Object draggedObject in DragAndDrop.objectReferences)
|
|
102
|
+
{
|
|
103
|
+
if (draggedObject == null)
|
|
104
|
+
{
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
string path = AssetDatabase.GetAssetPath(draggedObject);
|
|
109
|
+
if (string.IsNullOrWhiteSpace(path))
|
|
110
|
+
{
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (AssetDatabase.IsValidFolder(path))
|
|
115
|
+
{
|
|
116
|
+
TrySyncDirectory(path, _orderedTextures);
|
|
117
|
+
}
|
|
118
|
+
else if (
|
|
119
|
+
draggedObject is Texture2D texture
|
|
120
|
+
&& !_orderedTextures.Contains(texture)
|
|
121
|
+
)
|
|
122
|
+
{
|
|
123
|
+
_orderedTextures.Add(texture);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
EditorGUILayout.Space();
|
|
133
|
+
|
|
134
|
+
if (_orderedTextures.Count > 0 || _manualTextures.Count > 0)
|
|
135
|
+
{
|
|
136
|
+
EditorGUILayout.LabelField("Selected Images:", EditorStyles.boldLabel);
|
|
137
|
+
_scrollPosition = EditorGUILayout.BeginScrollView(
|
|
138
|
+
_scrollPosition,
|
|
139
|
+
GUILayout.Height(200)
|
|
140
|
+
);
|
|
141
|
+
foreach (Texture2D tex in _manualTextures.Concat(_orderedTextures).Distinct())
|
|
142
|
+
{
|
|
143
|
+
EditorGUILayout.ObjectField(tex.name, tex, typeof(Texture2D), false);
|
|
144
|
+
}
|
|
145
|
+
EditorGUILayout.EndScrollView();
|
|
146
|
+
|
|
147
|
+
if (GUILayout.Button("Clear Selection", _impactButtonStyle))
|
|
148
|
+
{
|
|
149
|
+
_orderedTextures.Clear();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else
|
|
153
|
+
{
|
|
154
|
+
EditorGUILayout.HelpBox(
|
|
155
|
+
"Drag images or folders into the area above to select them for blurring.",
|
|
156
|
+
MessageType.Info
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
EditorGUILayout.Space();
|
|
161
|
+
_blurRadius = EditorGUILayout.IntSlider("Blur Radius", _blurRadius, 1, 200);
|
|
162
|
+
EditorGUILayout.Space();
|
|
163
|
+
|
|
164
|
+
if (GUILayout.Button("Apply Blur", _impactButtonStyle))
|
|
165
|
+
{
|
|
166
|
+
ApplyBlurToSelectedTextures();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private static void TrySyncDirectory(string directory, List<Texture2D> output)
|
|
171
|
+
{
|
|
172
|
+
if (!AssetDatabase.IsValidFolder(directory))
|
|
173
|
+
{
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
string[] guids = AssetDatabase.FindAssets("t:Texture2D", new[] { directory });
|
|
178
|
+
foreach (string guid in guids)
|
|
179
|
+
{
|
|
180
|
+
Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(
|
|
181
|
+
AssetDatabase.GUIDToAssetPath(guid)
|
|
182
|
+
);
|
|
183
|
+
if (texture != null && !output.Contains(texture))
|
|
184
|
+
{
|
|
185
|
+
output.Add(texture);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private void ApplyBlurToSelectedTextures()
|
|
191
|
+
{
|
|
192
|
+
int processedCount = 0;
|
|
193
|
+
Texture2D[] toProcess = _manualTextures.Concat(_orderedTextures).Distinct().ToArray();
|
|
194
|
+
foreach (Texture2D originalTexture in toProcess)
|
|
195
|
+
{
|
|
196
|
+
string assetPath = AssetDatabase.GetAssetPath(originalTexture);
|
|
197
|
+
EditorUtility.DisplayProgressBar(
|
|
198
|
+
"Applying Blur",
|
|
199
|
+
$"Processing {originalTexture.name}...",
|
|
200
|
+
(float)processedCount / toProcess.Length
|
|
201
|
+
);
|
|
202
|
+
try
|
|
203
|
+
{
|
|
204
|
+
TextureImporter importer =
|
|
205
|
+
AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
|
206
|
+
|
|
207
|
+
bool importSettingsChanged = false;
|
|
208
|
+
|
|
209
|
+
if (importer != null)
|
|
210
|
+
{
|
|
211
|
+
if (!importer.isReadable)
|
|
212
|
+
{
|
|
213
|
+
importer.isReadable = true;
|
|
214
|
+
importSettingsChanged = true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (importer.textureCompression != TextureImporterCompression.Uncompressed)
|
|
218
|
+
{
|
|
219
|
+
importer.textureCompression = TextureImporterCompression.Uncompressed;
|
|
220
|
+
importSettingsChanged = true;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (importSettingsChanged)
|
|
224
|
+
{
|
|
225
|
+
importer.SaveAndReimport();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
Texture2D currentTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
|
|
230
|
+
|
|
231
|
+
if (currentTexture == null || !currentTexture.isReadable)
|
|
232
|
+
{
|
|
233
|
+
this.LogError(
|
|
234
|
+
$"Texture is null or could not be made readable: {assetPath}. Please check 'Read/Write Enabled' in its import settings if the issue persists. Skipping."
|
|
235
|
+
);
|
|
236
|
+
processedCount++;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
Texture2D blurredTexture = CreateBlurredTexture(currentTexture, _blurRadius);
|
|
241
|
+
|
|
242
|
+
if (blurredTexture != null)
|
|
243
|
+
{
|
|
244
|
+
string directory = Path.GetDirectoryName(assetPath);
|
|
245
|
+
if (string.IsNullOrWhiteSpace(directory))
|
|
246
|
+
{
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
string fileName = Path.GetFileNameWithoutExtension(assetPath);
|
|
251
|
+
string extension = Path.GetExtension(assetPath);
|
|
252
|
+
string newPathBase = Path.Combine(
|
|
253
|
+
directory,
|
|
254
|
+
$"{fileName}_blurred_{_blurRadius}"
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
string finalPath = newPathBase + extension;
|
|
258
|
+
int counter = 0;
|
|
259
|
+
while (File.Exists(finalPath))
|
|
260
|
+
{
|
|
261
|
+
counter++;
|
|
262
|
+
finalPath = $"{newPathBase}_{counter}{extension}";
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
byte[] bytes;
|
|
266
|
+
if (
|
|
267
|
+
string.Equals(extension, ".jpg", StringComparison.OrdinalIgnoreCase)
|
|
268
|
+
|| string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase)
|
|
269
|
+
)
|
|
270
|
+
{
|
|
271
|
+
bytes = blurredTexture.EncodeToJPG(100);
|
|
272
|
+
}
|
|
273
|
+
else
|
|
274
|
+
{
|
|
275
|
+
finalPath = Path.ChangeExtension(finalPath, ".png");
|
|
276
|
+
bytes = blurredTexture.EncodeToPNG();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (bytes != null)
|
|
280
|
+
{
|
|
281
|
+
File.WriteAllBytes(finalPath, bytes);
|
|
282
|
+
AssetDatabase.Refresh();
|
|
283
|
+
this.Log($"Saved blurred image to: {finalPath}");
|
|
284
|
+
}
|
|
285
|
+
else
|
|
286
|
+
{
|
|
287
|
+
this.LogError($"Failed to encode texture: {currentTexture.name}.");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
else
|
|
291
|
+
{
|
|
292
|
+
this.LogError(
|
|
293
|
+
$"Failed to create blurred texture for: {originalTexture.name}."
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
processedCount++;
|
|
298
|
+
}
|
|
299
|
+
finally
|
|
300
|
+
{
|
|
301
|
+
EditorUtility.ClearProgressBar();
|
|
302
|
+
EditorUtility.DisplayDialog(
|
|
303
|
+
"Blur Operation Complete",
|
|
304
|
+
$"Successfully blurred {processedCount} images.",
|
|
305
|
+
"OK"
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
private static Texture2D CreateBlurredTexture(Texture2D original, int radius)
|
|
312
|
+
{
|
|
313
|
+
Texture2D blurred = new(original.width, original.height, original.format, false);
|
|
314
|
+
Color[] pixels = original.GetPixels();
|
|
315
|
+
Color[] blurredPixels = new Color[pixels.Length];
|
|
316
|
+
int width = original.width;
|
|
317
|
+
int height = original.height;
|
|
318
|
+
|
|
319
|
+
// A temporary buffer for the first pass
|
|
320
|
+
Color[] tempPixels = new Color[pixels.Length];
|
|
321
|
+
|
|
322
|
+
// Generate the kernel for the weighted average
|
|
323
|
+
float[] kernel = GenerateGaussianKernel(radius);
|
|
324
|
+
|
|
325
|
+
// --- Horizontal Pass ---
|
|
326
|
+
Parallel.For(
|
|
327
|
+
0,
|
|
328
|
+
height,
|
|
329
|
+
y =>
|
|
330
|
+
{
|
|
331
|
+
int yOffset = y * width;
|
|
332
|
+
for (int x = 0; x < width; x++)
|
|
333
|
+
{
|
|
334
|
+
Color weightedSum = Color.clear;
|
|
335
|
+
float weightTotal = 0f;
|
|
336
|
+
|
|
337
|
+
for (int k = -radius; k <= radius; k++)
|
|
338
|
+
{
|
|
339
|
+
int currentX = x + k;
|
|
340
|
+
if (currentX >= 0 && currentX < width)
|
|
341
|
+
{
|
|
342
|
+
float weight = kernel[k + radius];
|
|
343
|
+
weightedSum += pixels[yOffset + currentX] * weight;
|
|
344
|
+
weightTotal += weight;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
tempPixels[yOffset + x] = weightedSum / weightTotal;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
// --- Vertical Pass ---
|
|
353
|
+
Parallel.For(
|
|
354
|
+
0,
|
|
355
|
+
width,
|
|
356
|
+
x =>
|
|
357
|
+
{
|
|
358
|
+
for (int y = 0; y < height; y++)
|
|
359
|
+
{
|
|
360
|
+
Color weightedSum = Color.clear;
|
|
361
|
+
float weightTotal = 0f;
|
|
362
|
+
|
|
363
|
+
for (int k = -radius; k <= radius; k++)
|
|
364
|
+
{
|
|
365
|
+
int currentY = y + k;
|
|
366
|
+
if (currentY >= 0 && currentY < height)
|
|
367
|
+
{
|
|
368
|
+
float weight = kernel[k + radius];
|
|
369
|
+
weightedSum += tempPixels[currentY * width + x] * weight;
|
|
370
|
+
weightTotal += weight;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
blurredPixels[y * width + x] = weightedSum / weightTotal;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
blurred.SetPixels(blurredPixels);
|
|
379
|
+
blurred.Apply();
|
|
380
|
+
return blurred;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
private static float[] GenerateGaussianKernel(int radius)
|
|
384
|
+
{
|
|
385
|
+
int size = radius * 2 + 1;
|
|
386
|
+
float[] kernel = new float[size];
|
|
387
|
+
float sigma = radius / 3.0f; // A good rule of thumb for sigma
|
|
388
|
+
float twoSigmaSquare = 2.0f * sigma * sigma;
|
|
389
|
+
float sum = 0f;
|
|
390
|
+
|
|
391
|
+
for (int i = 0; i < size; i++)
|
|
392
|
+
{
|
|
393
|
+
int distance = i - radius;
|
|
394
|
+
kernel[i] =
|
|
395
|
+
Mathf.Exp(-(distance * distance) / twoSigmaSquare)
|
|
396
|
+
/ (Mathf.Sqrt(Mathf.PI * twoSigmaSquare));
|
|
397
|
+
sum += kernel[i];
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Normalize the kernel so that the weights sum to 1
|
|
401
|
+
for (int i = 0; i < size; i++)
|
|
402
|
+
{
|
|
403
|
+
kernel[i] /= sum;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return kernel;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Editor.Visuals
|
|
2
|
+
{
|
|
3
|
+
#if UNITY_EDITOR
|
|
4
|
+
using System;
|
|
5
|
+
using UnityEditor;
|
|
6
|
+
using UnityEngine;
|
|
7
|
+
using UnityEngine.UI;
|
|
8
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
9
|
+
using WallstopStudios.UnityHelpers.Visuals.UGUI;
|
|
10
|
+
using Object = UnityEngine.Object;
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
This is needed because Unity already has a custom Inspector for Images which will not display our nice, cool new
|
|
14
|
+
fields.
|
|
15
|
+
*/
|
|
16
|
+
[CustomEditor(typeof(EnhancedImage))]
|
|
17
|
+
[CanEditMultipleObjects]
|
|
18
|
+
public sealed class ImageExtendedEditor : UnityEditor.UI.ImageEditor
|
|
19
|
+
{
|
|
20
|
+
private SerializedProperty _hdrColorProperty;
|
|
21
|
+
private SerializedProperty _shapeMaskProperty;
|
|
22
|
+
|
|
23
|
+
private GUIStyle _impactButtonStyle;
|
|
24
|
+
|
|
25
|
+
protected override void OnEnable()
|
|
26
|
+
{
|
|
27
|
+
base.OnEnable();
|
|
28
|
+
_hdrColorProperty = serializedObject.FindProperty(nameof(EnhancedImage._hdrColor));
|
|
29
|
+
_shapeMaskProperty = serializedObject.FindProperty(nameof(EnhancedImage._shapeMask));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public override void OnInspectorGUI()
|
|
33
|
+
{
|
|
34
|
+
_impactButtonStyle ??= new GUIStyle(GUI.skin.button)
|
|
35
|
+
{
|
|
36
|
+
normal = { textColor = Color.yellow },
|
|
37
|
+
fontStyle = FontStyle.Bold,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
serializedObject.Update();
|
|
41
|
+
|
|
42
|
+
EditorGUILayout.Space();
|
|
43
|
+
EditorGUILayout.LabelField("Extended Properties", EditorStyles.boldLabel);
|
|
44
|
+
|
|
45
|
+
EnhancedImage instance = target as EnhancedImage;
|
|
46
|
+
if (
|
|
47
|
+
instance != null
|
|
48
|
+
&& (
|
|
49
|
+
instance.material == null
|
|
50
|
+
|| string.Equals(
|
|
51
|
+
instance.material.name,
|
|
52
|
+
"Default UI Material",
|
|
53
|
+
StringComparison.Ordinal
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
&& GUILayout.Button("Incorrect Material Detected - Try Fix?", _impactButtonStyle)
|
|
57
|
+
)
|
|
58
|
+
{
|
|
59
|
+
string currentPath = DirectoryHelper.GetCallerScriptDirectory();
|
|
60
|
+
string packagePath = DirectoryHelper.FindPackageRootPath(currentPath);
|
|
61
|
+
string materialPathFullPath =
|
|
62
|
+
$"{packagePath}/Shaders/Materials/BackgroundMask-Material.mat".SanitizePath();
|
|
63
|
+
string materialRelativePath = DirectoryHelper.AbsoluteToUnityRelativePath(
|
|
64
|
+
materialPathFullPath
|
|
65
|
+
);
|
|
66
|
+
Material defaultMask = AssetDatabase.LoadAssetAtPath<Material>(
|
|
67
|
+
materialRelativePath
|
|
68
|
+
);
|
|
69
|
+
if (defaultMask != null)
|
|
70
|
+
{
|
|
71
|
+
instance.material = defaultMask;
|
|
72
|
+
}
|
|
73
|
+
else
|
|
74
|
+
{
|
|
75
|
+
Debug.LogError($"Failed to load material at path '{materialRelativePath}'.");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
EditorGUILayout.PropertyField(_hdrColorProperty, new GUIContent("HDR Color"));
|
|
80
|
+
EditorGUILayout.PropertyField(
|
|
81
|
+
_shapeMaskProperty,
|
|
82
|
+
new GUIContent(
|
|
83
|
+
"Shape Mask",
|
|
84
|
+
"Material shader must have an exposed _ShapeMask texture2D property to function. Otherwise, this does nothing."
|
|
85
|
+
)
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
EditorGUILayout.Space();
|
|
89
|
+
|
|
90
|
+
serializedObject.ApplyModifiedProperties();
|
|
91
|
+
|
|
92
|
+
serializedObject.Update();
|
|
93
|
+
DrawPropertiesExcluding(serializedObject, nameof(Image.material));
|
|
94
|
+
serializedObject.ApplyModifiedProperties();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Set the icon for ImageExtended to match the icon of the Image component
|
|
99
|
+
[InitializeOnLoad]
|
|
100
|
+
public static class ImageExtendedIcon
|
|
101
|
+
{
|
|
102
|
+
private static EnhancedImage IconReference;
|
|
103
|
+
|
|
104
|
+
static ImageExtendedIcon()
|
|
105
|
+
{
|
|
106
|
+
IconReference = new GameObject("Icon Object")
|
|
107
|
+
{
|
|
108
|
+
hideFlags = HideFlags.HideAndDontSave,
|
|
109
|
+
}.AddComponent<EnhancedImage>();
|
|
110
|
+
|
|
111
|
+
EditorGUIUtility.SetIconForObject(
|
|
112
|
+
MonoScript.FromMonoBehaviour(IconReference),
|
|
113
|
+
EditorGUIUtility.IconContent("Image Icon").image as Texture2D
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private static void OnBeforeAssemblyReload()
|
|
120
|
+
{
|
|
121
|
+
if (IconReference == null)
|
|
122
|
+
{
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
Object.DestroyImmediate(IconReference.gameObject);
|
|
127
|
+
IconReference = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
#endif
|
|
131
|
+
}
|