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
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Visuals
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.Linq;
|
|
6
|
+
using UnityEngine;
|
|
7
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
8
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
9
|
+
|
|
10
|
+
public readonly struct AnimatedSpriteLayer : IEquatable<AnimatedSpriteLayer>
|
|
11
|
+
{
|
|
12
|
+
public const float FrameRate = 12f;
|
|
13
|
+
|
|
14
|
+
public readonly Vector2[] perFramePixelOffsets;
|
|
15
|
+
public readonly Sprite[] frames;
|
|
16
|
+
public readonly float alpha;
|
|
17
|
+
|
|
18
|
+
public AnimatedSpriteLayer(
|
|
19
|
+
IEnumerable<Sprite> sprites,
|
|
20
|
+
IEnumerable<Vector2> worldSpaceOffsets = null,
|
|
21
|
+
float alpha = 1
|
|
22
|
+
)
|
|
23
|
+
{
|
|
24
|
+
frames = sprites?.ToArray() ?? Array.Empty<Sprite>();
|
|
25
|
+
foreach (Sprite frame in frames)
|
|
26
|
+
{
|
|
27
|
+
if (frame == null)
|
|
28
|
+
{
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
frame.texture.MakeReadable();
|
|
33
|
+
try
|
|
34
|
+
{
|
|
35
|
+
frame.texture.GetPixel(0, 0);
|
|
36
|
+
}
|
|
37
|
+
catch (UnityException e)
|
|
38
|
+
{
|
|
39
|
+
Debug.LogError(
|
|
40
|
+
$"Texture '{frame.texture.name}' for sprite '{frame.name}' is not readable. Please enable Read/Write in its import settings. Error: {e.Message}"
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (worldSpaceOffsets != null && frames is { Length: > 0 })
|
|
46
|
+
{
|
|
47
|
+
perFramePixelOffsets = worldSpaceOffsets
|
|
48
|
+
.Zip(
|
|
49
|
+
frames,
|
|
50
|
+
(offset, frame) =>
|
|
51
|
+
frame != null && frame.pixelsPerUnit > 0
|
|
52
|
+
? frame.pixelsPerUnit * offset
|
|
53
|
+
: Vector2.zero
|
|
54
|
+
)
|
|
55
|
+
.ToArray();
|
|
56
|
+
if (Debug.isDebugBuild)
|
|
57
|
+
{
|
|
58
|
+
Debug.Assert(
|
|
59
|
+
perFramePixelOffsets.Length == frames.Length,
|
|
60
|
+
$"Expected {frames.Length} sprite frames to match {perFramePixelOffsets.Length} offsets after processing."
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else
|
|
65
|
+
{
|
|
66
|
+
perFramePixelOffsets = null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
this.alpha = Mathf.Clamp01(alpha);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public AnimatedSpriteLayer(
|
|
73
|
+
AnimationClip clip,
|
|
74
|
+
IEnumerable<Vector2> worldSpaceOffsets = null,
|
|
75
|
+
float alpha = 1
|
|
76
|
+
)
|
|
77
|
+
: this(
|
|
78
|
+
#if UNITY_EDITOR
|
|
79
|
+
clip.GetSpritesFromClip(),
|
|
80
|
+
#else
|
|
81
|
+
Enumerable.Empty<Sprite>(),
|
|
82
|
+
#endif
|
|
83
|
+
worldSpaceOffsets, alpha) { }
|
|
84
|
+
|
|
85
|
+
public static bool operator ==(AnimatedSpriteLayer left, AnimatedSpriteLayer right)
|
|
86
|
+
{
|
|
87
|
+
return left.Equals(right);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public static bool operator !=(AnimatedSpriteLayer left, AnimatedSpriteLayer right)
|
|
91
|
+
{
|
|
92
|
+
return !left.Equals(right);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public bool Equals(AnimatedSpriteLayer other)
|
|
96
|
+
{
|
|
97
|
+
bool equal = perFramePixelOffsets.AsSpan().SequenceEqual(other.perFramePixelOffsets);
|
|
98
|
+
if (!equal)
|
|
99
|
+
{
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
equal = frames.Length == other.frames.Length;
|
|
104
|
+
if (!equal)
|
|
105
|
+
{
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
for (int i = 0; i < frames.Length; ++i)
|
|
110
|
+
{
|
|
111
|
+
if (frames[i] != other.frames[i])
|
|
112
|
+
{
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return alpha.Equals(other.alpha);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public override bool Equals(object obj)
|
|
121
|
+
{
|
|
122
|
+
return obj is AnimatedSpriteLayer other && Equals(other);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public override int GetHashCode()
|
|
126
|
+
{
|
|
127
|
+
return Objects.ValueTypeHashCode(perFramePixelOffsets.Length, frames.Length, alpha);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
using System.Runtime.CompilerServices;
|
|
2
|
+
|
|
3
|
+
[assembly: InternalsVisibleTo("WallstopStudios.UnityHelpers.Editor", AllInternalsVisible = true)]
|
|
4
|
+
|
|
5
|
+
namespace WallstopStudios.UnityHelpers.Visuals.UGUI
|
|
6
|
+
{
|
|
7
|
+
using UnityEngine;
|
|
8
|
+
using UnityEngine.Serialization;
|
|
9
|
+
using UnityEngine.UI;
|
|
10
|
+
|
|
11
|
+
public sealed class EnhancedImage : Image
|
|
12
|
+
{
|
|
13
|
+
private static readonly int ShapeMaskPropertyID = Shader.PropertyToID("_ShapeMask");
|
|
14
|
+
private static readonly int ColorPropertyID = Shader.PropertyToID("_Color");
|
|
15
|
+
|
|
16
|
+
public Color HdrColor
|
|
17
|
+
{
|
|
18
|
+
get => _hdrColor;
|
|
19
|
+
set
|
|
20
|
+
{
|
|
21
|
+
if (_hdrColor == value)
|
|
22
|
+
{
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
_hdrColor = value;
|
|
26
|
+
UpdateMaterialInstance();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ShapeMask: This functionality mimics Unity's UI mask components, but works with custom materials
|
|
31
|
+
// To function, your image material must use a shader with a Texture2D property of this name, its
|
|
32
|
+
// alpha mapped to the sprite shader's alpha
|
|
33
|
+
[FormerlySerializedAs("shapeMask")]
|
|
34
|
+
[SerializeField]
|
|
35
|
+
internal Texture2D _shapeMask;
|
|
36
|
+
|
|
37
|
+
// HDR Color field that will override the base Image color if values set > 1
|
|
38
|
+
[FormerlySerializedAs("hdrColor")]
|
|
39
|
+
[SerializeField]
|
|
40
|
+
[ColorUsage(showAlpha: true, hdr: true)]
|
|
41
|
+
internal Color _hdrColor = Color.white;
|
|
42
|
+
|
|
43
|
+
protected override void Start()
|
|
44
|
+
{
|
|
45
|
+
base.Start();
|
|
46
|
+
UpdateMaterialInstance();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
protected override void OnValidate()
|
|
50
|
+
{
|
|
51
|
+
base.OnValidate();
|
|
52
|
+
UpdateMaterialInstance();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private void UpdateMaterialInstance()
|
|
56
|
+
{
|
|
57
|
+
Material localMaterial = material;
|
|
58
|
+
if (localMaterial == null)
|
|
59
|
+
{
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
Material materialInstance = new(localMaterial);
|
|
64
|
+
if (_shapeMask != null)
|
|
65
|
+
{
|
|
66
|
+
materialInstance.SetTexture(ShapeMaskPropertyID, _shapeMask);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
materialInstance.SetColor(
|
|
70
|
+
ColorPropertyID,
|
|
71
|
+
_hdrColor.maxColorComponent > 1 ? _hdrColor : color
|
|
72
|
+
);
|
|
73
|
+
material = materialInstance;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,137 +1,15 @@
|
|
|
1
|
-
namespace WallstopStudios.UnityHelpers.
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Visuals.UIToolkit
|
|
2
2
|
{
|
|
3
3
|
using System;
|
|
4
4
|
using System.Collections.Generic;
|
|
5
5
|
using System.Diagnostics;
|
|
6
6
|
using System.Linq;
|
|
7
7
|
using System.Threading.Tasks;
|
|
8
|
-
using
|
|
9
|
-
using Core.Helper;
|
|
8
|
+
using UnityEditor;
|
|
10
9
|
using UnityEngine;
|
|
11
10
|
using UnityEngine.UIElements;
|
|
12
|
-
using
|
|
13
|
-
using
|
|
14
|
-
#if UNITY_EDITOR
|
|
15
|
-
using UnityEditor;
|
|
16
|
-
#endif
|
|
17
|
-
|
|
18
|
-
public readonly struct AnimatedSpriteLayer : IEquatable<AnimatedSpriteLayer>
|
|
19
|
-
{
|
|
20
|
-
public const float FrameRate = 12f;
|
|
21
|
-
|
|
22
|
-
public readonly Vector2[] perFramePixelOffsets;
|
|
23
|
-
public readonly Sprite[] frames;
|
|
24
|
-
public readonly float alpha;
|
|
25
|
-
|
|
26
|
-
public AnimatedSpriteLayer(
|
|
27
|
-
IEnumerable<Sprite> sprites,
|
|
28
|
-
IEnumerable<Vector2> worldSpaceOffsets = null,
|
|
29
|
-
float alpha = 1
|
|
30
|
-
)
|
|
31
|
-
{
|
|
32
|
-
frames = sprites?.ToArray() ?? Array.Empty<Sprite>();
|
|
33
|
-
foreach (Sprite frame in frames)
|
|
34
|
-
{
|
|
35
|
-
if (frame == null)
|
|
36
|
-
{
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
frame.texture.MakeReadable();
|
|
41
|
-
try
|
|
42
|
-
{
|
|
43
|
-
frame.texture.GetPixel(0, 0);
|
|
44
|
-
}
|
|
45
|
-
catch (UnityException e)
|
|
46
|
-
{
|
|
47
|
-
Debug.LogError(
|
|
48
|
-
$"Texture '{frame.texture.name}' for sprite '{frame.name}' is not readable. Please enable Read/Write in its import settings. Error: {e.Message}"
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (worldSpaceOffsets != null && frames is { Length: > 0 })
|
|
54
|
-
{
|
|
55
|
-
perFramePixelOffsets = worldSpaceOffsets
|
|
56
|
-
.Zip(
|
|
57
|
-
frames,
|
|
58
|
-
(offset, frame) =>
|
|
59
|
-
frame != null && frame.pixelsPerUnit > 0
|
|
60
|
-
? frame.pixelsPerUnit * offset
|
|
61
|
-
: Vector2.zero
|
|
62
|
-
)
|
|
63
|
-
.ToArray();
|
|
64
|
-
Debug.Assert(
|
|
65
|
-
perFramePixelOffsets.Length == frames.Length,
|
|
66
|
-
$"Expected {frames.Length} sprite frames to match {perFramePixelOffsets.Length} offsets after processing."
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
else
|
|
70
|
-
{
|
|
71
|
-
perFramePixelOffsets = null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
this.alpha = Mathf.Clamp01(alpha);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
public AnimatedSpriteLayer(
|
|
78
|
-
AnimationClip clip,
|
|
79
|
-
IEnumerable<Vector2> worldSpaceOffsets = null,
|
|
80
|
-
float alpha = 1
|
|
81
|
-
)
|
|
82
|
-
: this(
|
|
83
|
-
#if UNITY_EDITOR
|
|
84
|
-
clip.GetSpritesFromClip(),
|
|
85
|
-
#else
|
|
86
|
-
Enumerable.Empty<Sprite>(),
|
|
87
|
-
#endif
|
|
88
|
-
worldSpaceOffsets, alpha) { }
|
|
89
|
-
|
|
90
|
-
public static bool operator ==(AnimatedSpriteLayer left, AnimatedSpriteLayer right)
|
|
91
|
-
{
|
|
92
|
-
return left.Equals(right);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
public static bool operator !=(AnimatedSpriteLayer left, AnimatedSpriteLayer right)
|
|
96
|
-
{
|
|
97
|
-
return !left.Equals(right);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
public bool Equals(AnimatedSpriteLayer other)
|
|
101
|
-
{
|
|
102
|
-
bool equal = perFramePixelOffsets.AsSpan().SequenceEqual(other.perFramePixelOffsets);
|
|
103
|
-
if (!equal)
|
|
104
|
-
{
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
equal = frames.Length == other.frames.Length;
|
|
109
|
-
if (!equal)
|
|
110
|
-
{
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
for (int i = 0; i < frames.Length; ++i)
|
|
115
|
-
{
|
|
116
|
-
if (frames[i] != other.frames[i])
|
|
117
|
-
{
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return alpha.Equals(other.alpha);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
public override bool Equals(object obj)
|
|
126
|
-
{
|
|
127
|
-
return obj is AnimatedSpriteLayer other && Equals(other);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
public override int GetHashCode()
|
|
131
|
-
{
|
|
132
|
-
return Objects.ValueTypeHashCode(perFramePixelOffsets.Length, frames.Length, alpha);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
11
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
12
|
+
using WallstopStudios.UnityHelpers.Utils;
|
|
135
13
|
|
|
136
14
|
public sealed class LayeredImage : VisualElement
|
|
137
15
|
{
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
namespace WallstopStudios.UnityHelpers.
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Visuals.UIToolkit
|
|
2
2
|
{
|
|
3
3
|
using System;
|
|
4
4
|
using System.Collections.Generic;
|
|
5
5
|
using System.IO;
|
|
6
6
|
using System.Linq;
|
|
7
|
-
using Core.Extension;
|
|
8
|
-
using Core.Helper;
|
|
9
7
|
using UnityEngine;
|
|
10
8
|
using UnityEngine.UIElements;
|
|
9
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
10
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
11
11
|
|
|
12
12
|
public sealed class MultiFileSelectorElement : VisualElement
|
|
13
13
|
{
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
%YAML 1.1
|
|
2
|
+
%TAG !u! tag:unity3d.com,2011:
|
|
3
|
+
--- !u!114 &-1479414424530981672
|
|
4
|
+
MonoBehaviour:
|
|
5
|
+
m_ObjectHideFlags: 11
|
|
6
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
7
|
+
m_PrefabInstance: {fileID: 0}
|
|
8
|
+
m_PrefabAsset: {fileID: 0}
|
|
9
|
+
m_GameObject: {fileID: 0}
|
|
10
|
+
m_Enabled: 1
|
|
11
|
+
m_EditorHideFlags: 0
|
|
12
|
+
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
|
13
|
+
m_Name:
|
|
14
|
+
m_EditorClassIdentifier:
|
|
15
|
+
version: 7
|
|
16
|
+
--- !u!21 &2100000
|
|
17
|
+
Material:
|
|
18
|
+
serializedVersion: 8
|
|
19
|
+
m_ObjectHideFlags: 0
|
|
20
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
21
|
+
m_PrefabInstance: {fileID: 0}
|
|
22
|
+
m_PrefabAsset: {fileID: 0}
|
|
23
|
+
m_Name: BackgroundMask-Material
|
|
24
|
+
m_Shader: {fileID: -6465566751694194690, guid: 5f547121767cdd84ab771a0950431148, type: 3}
|
|
25
|
+
m_Parent: {fileID: 0}
|
|
26
|
+
m_ModifiedSerializedProperties: 0
|
|
27
|
+
m_ValidKeywords: []
|
|
28
|
+
m_InvalidKeywords: []
|
|
29
|
+
m_LightmapFlags: 4
|
|
30
|
+
m_EnableInstancingVariants: 0
|
|
31
|
+
m_DoubleSidedGI: 0
|
|
32
|
+
m_CustomRenderQueue: -1
|
|
33
|
+
stringTagMap: {}
|
|
34
|
+
disabledShaderPasses: []
|
|
35
|
+
m_LockedProperties:
|
|
36
|
+
m_SavedProperties:
|
|
37
|
+
serializedVersion: 3
|
|
38
|
+
m_TexEnvs:
|
|
39
|
+
- _MainTex:
|
|
40
|
+
m_Texture: {fileID: 0}
|
|
41
|
+
m_Scale: {x: 1, y: 1}
|
|
42
|
+
m_Offset: {x: 0, y: 0}
|
|
43
|
+
- unity_Lightmaps:
|
|
44
|
+
m_Texture: {fileID: 0}
|
|
45
|
+
m_Scale: {x: 1, y: 1}
|
|
46
|
+
m_Offset: {x: 0, y: 0}
|
|
47
|
+
- unity_LightmapsInd:
|
|
48
|
+
m_Texture: {fileID: 0}
|
|
49
|
+
m_Scale: {x: 1, y: 1}
|
|
50
|
+
m_Offset: {x: 0, y: 0}
|
|
51
|
+
- unity_ShadowMasks:
|
|
52
|
+
m_Texture: {fileID: 0}
|
|
53
|
+
m_Scale: {x: 1, y: 1}
|
|
54
|
+
m_Offset: {x: 0, y: 0}
|
|
55
|
+
m_Ints: []
|
|
56
|
+
m_Floats: []
|
|
57
|
+
m_Colors:
|
|
58
|
+
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
|
59
|
+
m_BuildTextureStacks: []
|