com.wallstop-studios.unity-helpers 2.0.0-rc76.6 → 2.0.0-rc76.7
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/AssetProcessors/SpriteLabelProcessor.cs +133 -0
- package/Editor/AssetProcessors/SpriteLabelProcessor.cs.meta +3 -0
- package/Editor/AssetProcessors.meta +3 -0
- package/Editor/CustomDrawers/StringInListeDrawer.cs +104 -25
- package/Editor/CustomDrawers/WShowIfPropertyDrawer.cs +12 -4
- package/Editor/CustomEditors/SourceFolderEntryDrawer.cs +182 -57
- package/Editor/Extensions/SerializedPropertyExtensions.cs +11 -0
- package/Editor/Sprites/ScriptableSpriteAtlas.cs +71 -1
- package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs +85 -33
- package/Editor/Sprites/SpriteSheetAnimationCreator.cs +408 -96
- package/Runtime/Core/Attributes/WShowIfAttribute.cs +9 -1
- package/Runtime/Core/Helper/Helpers.cs +31 -3
- package/Runtime/Core/Helper/StringInList.cs +22 -3
- package/package.json +2 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// ReSharper disable HeapView.CanAvoidClosure
|
|
2
|
+
namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
2
3
|
{
|
|
3
4
|
#if UNITY_EDITOR
|
|
4
5
|
using System;
|
|
@@ -13,7 +14,6 @@
|
|
|
13
14
|
using UnityEditor.UIElements;
|
|
14
15
|
using UnityEngine;
|
|
15
16
|
using UnityEngine.UIElements;
|
|
16
|
-
using Debug = UnityEngine.Debug;
|
|
17
17
|
using Object = UnityEngine.Object;
|
|
18
18
|
|
|
19
19
|
public sealed class SpriteSheetAnimationCreator : EditorWindow
|
|
@@ -43,6 +43,14 @@
|
|
|
43
43
|
private Button _nextFrameButton;
|
|
44
44
|
private Slider _previewScrubber;
|
|
45
45
|
|
|
46
|
+
private bool _isDraggingToSelectSprites;
|
|
47
|
+
private int _spriteSelectionDragStartIndex = -1;
|
|
48
|
+
private int _spriteSelectionDragCurrentIndex = -1;
|
|
49
|
+
private StyleColor _selectedThumbnailBackgroundColor = new(
|
|
50
|
+
new Color(0.2f, 0.5f, 0.8f, 0.4f)
|
|
51
|
+
);
|
|
52
|
+
private readonly StyleColor _defaultThumbnailBackgroundColor = new(StyleKeyword.Null);
|
|
53
|
+
|
|
46
54
|
private bool _isPreviewing;
|
|
47
55
|
private int _currentPreviewAnimDefIndex = -1;
|
|
48
56
|
private int _currentPreviewSpriteIndex;
|
|
@@ -65,6 +73,8 @@
|
|
|
65
73
|
public sealed class AnimationDefinition
|
|
66
74
|
{
|
|
67
75
|
public string Name = "New Animation";
|
|
76
|
+
public bool loop;
|
|
77
|
+
public float cycleOffset;
|
|
68
78
|
public int StartSpriteIndex;
|
|
69
79
|
public int EndSpriteIndex;
|
|
70
80
|
public float DefaultFrameRate = 12f;
|
|
@@ -79,6 +89,8 @@
|
|
|
79
89
|
public Label spriteCountLabel;
|
|
80
90
|
public Button previewButton;
|
|
81
91
|
public Button removeButton;
|
|
92
|
+
public Toggle loopingField;
|
|
93
|
+
public FloatField cycleOffsetField;
|
|
82
94
|
}
|
|
83
95
|
|
|
84
96
|
public SpriteSheetAnimationCreator()
|
|
@@ -161,7 +173,9 @@
|
|
|
161
173
|
topSection.Add(_refreshSpritesButton);
|
|
162
174
|
root.Add(topSection);
|
|
163
175
|
|
|
164
|
-
Label thumbnailsLabel = new(
|
|
176
|
+
Label thumbnailsLabel = new(
|
|
177
|
+
"Available Sprites (Drag to select range for new animation):"
|
|
178
|
+
)
|
|
165
179
|
{
|
|
166
180
|
style =
|
|
167
181
|
{
|
|
@@ -175,8 +189,8 @@
|
|
|
175
189
|
{
|
|
176
190
|
style =
|
|
177
191
|
{
|
|
178
|
-
height = ThumbnailSize + 20,
|
|
179
|
-
minHeight = ThumbnailSize + 20,
|
|
192
|
+
height = ThumbnailSize + 20 + 10,
|
|
193
|
+
minHeight = ThumbnailSize + 20 + 10,
|
|
180
194
|
borderTopWidth = 1,
|
|
181
195
|
borderBottomWidth = 1,
|
|
182
196
|
borderLeftWidth = 1,
|
|
@@ -196,6 +210,72 @@
|
|
|
196
210
|
{
|
|
197
211
|
style = { flexDirection = FlexDirection.Row },
|
|
198
212
|
};
|
|
213
|
+
|
|
214
|
+
_spriteThumbnailsContainer.RegisterCallback<PointerMoveEvent>(evt =>
|
|
215
|
+
{
|
|
216
|
+
if (
|
|
217
|
+
_isDraggingToSelectSprites
|
|
218
|
+
&& _spriteThumbnailsContainer.HasPointerCapture(evt.pointerId)
|
|
219
|
+
)
|
|
220
|
+
{
|
|
221
|
+
VisualElement currentElementOver = evt.target as VisualElement;
|
|
222
|
+
|
|
223
|
+
VisualElement thumbChild = currentElementOver;
|
|
224
|
+
while (thumbChild != null && thumbChild.parent != _spriteThumbnailsContainer)
|
|
225
|
+
{
|
|
226
|
+
thumbChild = thumbChild.parent;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (
|
|
230
|
+
thumbChild is { userData: int hoveredIndex }
|
|
231
|
+
&& _spriteSelectionDragCurrentIndex != hoveredIndex
|
|
232
|
+
)
|
|
233
|
+
{
|
|
234
|
+
_spriteSelectionDragCurrentIndex = hoveredIndex;
|
|
235
|
+
UpdateSpriteSelectionHighlight();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
_spriteThumbnailsContainer.RegisterCallback<PointerUpEvent>(
|
|
241
|
+
evt =>
|
|
242
|
+
{
|
|
243
|
+
if (
|
|
244
|
+
evt.button == 0
|
|
245
|
+
&& _isDraggingToSelectSprites
|
|
246
|
+
&& _spriteThumbnailsContainer.HasPointerCapture(evt.pointerId)
|
|
247
|
+
)
|
|
248
|
+
{
|
|
249
|
+
_spriteThumbnailsContainer.ReleasePointer(evt.pointerId);
|
|
250
|
+
_isDraggingToSelectSprites = false;
|
|
251
|
+
|
|
252
|
+
if (
|
|
253
|
+
_spriteSelectionDragStartIndex != -1
|
|
254
|
+
&& _spriteSelectionDragCurrentIndex != -1
|
|
255
|
+
)
|
|
256
|
+
{
|
|
257
|
+
int start = Mathf.Min(
|
|
258
|
+
_spriteSelectionDragStartIndex,
|
|
259
|
+
_spriteSelectionDragCurrentIndex
|
|
260
|
+
);
|
|
261
|
+
int end = Mathf.Max(
|
|
262
|
+
_spriteSelectionDragStartIndex,
|
|
263
|
+
_spriteSelectionDragCurrentIndex
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
if (start <= end)
|
|
267
|
+
{
|
|
268
|
+
CreateAnimationDefinitionFromSelection(start, end);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
ClearSpriteSelectionHighlight();
|
|
272
|
+
_spriteSelectionDragStartIndex = -1;
|
|
273
|
+
_spriteSelectionDragCurrentIndex = -1;
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
TrickleDown.TrickleDown
|
|
277
|
+
);
|
|
278
|
+
|
|
199
279
|
_spriteThumbnailsScrollView.Add(_spriteThumbnailsContainer);
|
|
200
280
|
root.Add(_spriteThumbnailsScrollView);
|
|
201
281
|
|
|
@@ -424,6 +504,115 @@
|
|
|
424
504
|
SetPreviewFrame(nextFrame);
|
|
425
505
|
}
|
|
426
506
|
|
|
507
|
+
private void UpdateSpriteSelectionHighlight()
|
|
508
|
+
{
|
|
509
|
+
if (
|
|
510
|
+
!_isDraggingToSelectSprites
|
|
511
|
+
|| _spriteSelectionDragStartIndex == -1
|
|
512
|
+
|| _spriteSelectionDragCurrentIndex == -1
|
|
513
|
+
)
|
|
514
|
+
{
|
|
515
|
+
ClearSpriteSelectionHighlight();
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
int minIdx = Mathf.Min(
|
|
520
|
+
_spriteSelectionDragStartIndex,
|
|
521
|
+
_spriteSelectionDragCurrentIndex
|
|
522
|
+
);
|
|
523
|
+
int maxIdx = Mathf.Max(
|
|
524
|
+
_spriteSelectionDragStartIndex,
|
|
525
|
+
_spriteSelectionDragCurrentIndex
|
|
526
|
+
);
|
|
527
|
+
|
|
528
|
+
for (int i = 0; i < _spriteThumbnailsContainer.childCount; i++)
|
|
529
|
+
{
|
|
530
|
+
VisualElement thumb = _spriteThumbnailsContainer.ElementAt(i);
|
|
531
|
+
if (thumb.userData is int thumbIndex)
|
|
532
|
+
{
|
|
533
|
+
if (thumbIndex >= minIdx && thumbIndex <= maxIdx)
|
|
534
|
+
{
|
|
535
|
+
thumb.style.backgroundColor = _selectedThumbnailBackgroundColor;
|
|
536
|
+
thumb.style.borderBottomColor =
|
|
537
|
+
_selectedThumbnailBackgroundColor.value * 1.5f;
|
|
538
|
+
thumb.style.borderTopColor = _selectedThumbnailBackgroundColor.value * 1.5f;
|
|
539
|
+
thumb.style.borderLeftColor =
|
|
540
|
+
_selectedThumbnailBackgroundColor.value * 1.5f;
|
|
541
|
+
thumb.style.borderRightColor =
|
|
542
|
+
_selectedThumbnailBackgroundColor.value * 1.5f;
|
|
543
|
+
}
|
|
544
|
+
else
|
|
545
|
+
{
|
|
546
|
+
thumb.style.backgroundColor = _defaultThumbnailBackgroundColor;
|
|
547
|
+
thumb.style.borderBottomColor = Color.clear;
|
|
548
|
+
thumb.style.borderTopColor = Color.clear;
|
|
549
|
+
thumb.style.borderLeftColor = Color.clear;
|
|
550
|
+
thumb.style.borderRightColor = Color.clear;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
private void ClearSpriteSelectionHighlight()
|
|
557
|
+
{
|
|
558
|
+
for (int i = 0; i < _spriteThumbnailsContainer.childCount; i++)
|
|
559
|
+
{
|
|
560
|
+
VisualElement thumb = _spriteThumbnailsContainer.ElementAt(i);
|
|
561
|
+
thumb.style.backgroundColor = _defaultThumbnailBackgroundColor;
|
|
562
|
+
thumb.style.borderBottomColor = Color.clear;
|
|
563
|
+
thumb.style.borderTopColor = Color.clear;
|
|
564
|
+
thumb.style.borderLeftColor = Color.clear;
|
|
565
|
+
thumb.style.borderRightColor = Color.clear;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
private void CreateAnimationDefinitionFromSelection(
|
|
570
|
+
int startSpriteIndex,
|
|
571
|
+
int endSpriteIndex
|
|
572
|
+
)
|
|
573
|
+
{
|
|
574
|
+
if (
|
|
575
|
+
startSpriteIndex < 0
|
|
576
|
+
|| endSpriteIndex < 0
|
|
577
|
+
|| startSpriteIndex >= _availableSprites.Count
|
|
578
|
+
|| endSpriteIndex >= _availableSprites.Count
|
|
579
|
+
)
|
|
580
|
+
{
|
|
581
|
+
this.LogWarn(
|
|
582
|
+
$"Invalid sprite indices for new animation definition from selection."
|
|
583
|
+
);
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
AnimationDefinition newDefinition = new()
|
|
588
|
+
{
|
|
589
|
+
Name =
|
|
590
|
+
_selectedSpriteSheet != null
|
|
591
|
+
? $"{_selectedSpriteSheet.name}_Anim_{_animationDefinitions.Count}"
|
|
592
|
+
: $"New_Animation_{_animationDefinitions.Count}",
|
|
593
|
+
StartSpriteIndex = startSpriteIndex,
|
|
594
|
+
EndSpriteIndex = endSpriteIndex,
|
|
595
|
+
DefaultFrameRate = 12f,
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
newDefinition.FrameRateCurve = AnimationCurve.Constant(
|
|
599
|
+
0,
|
|
600
|
+
1,
|
|
601
|
+
newDefinition.DefaultFrameRate
|
|
602
|
+
);
|
|
603
|
+
|
|
604
|
+
_animationDefinitions.Add(newDefinition);
|
|
605
|
+
UpdateSpritesForDefinition(newDefinition);
|
|
606
|
+
_currentPreviewAnimDefIndex = _animationDefinitions.Count - 1;
|
|
607
|
+
StartOrUpdateCurrentPreview(newDefinition);
|
|
608
|
+
_animationDefinitionsListView.Rebuild();
|
|
609
|
+
|
|
610
|
+
if (_animationDefinitionsListView.itemsSource.Count > 0)
|
|
611
|
+
{
|
|
612
|
+
_animationDefinitionsListView.ScrollToItem(_animationDefinitions.Count - 1);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
427
616
|
private void OnSpriteSheetSelected(ChangeEvent<Object> evt)
|
|
428
617
|
{
|
|
429
618
|
_selectedSpriteSheet = evt.newValue as Texture2D;
|
|
@@ -540,7 +729,20 @@
|
|
|
540
729
|
Sprite sprite = _availableSprites[i];
|
|
541
730
|
VisualElement thumbContainer = new()
|
|
542
731
|
{
|
|
543
|
-
style =
|
|
732
|
+
style =
|
|
733
|
+
{
|
|
734
|
+
alignItems = Align.Center,
|
|
735
|
+
marginRight = 5,
|
|
736
|
+
paddingBottom = 2,
|
|
737
|
+
borderBottomWidth = 1,
|
|
738
|
+
borderLeftWidth = 1,
|
|
739
|
+
borderRightWidth = 1,
|
|
740
|
+
borderTopWidth = 1,
|
|
741
|
+
borderBottomColor = Color.clear,
|
|
742
|
+
borderTopColor = Color.clear,
|
|
743
|
+
borderLeftColor = Color.clear,
|
|
744
|
+
borderRightColor = Color.clear,
|
|
745
|
+
},
|
|
544
746
|
};
|
|
545
747
|
Image img = new()
|
|
546
748
|
{
|
|
@@ -550,6 +752,36 @@
|
|
|
550
752
|
};
|
|
551
753
|
thumbContainer.Add(img);
|
|
552
754
|
thumbContainer.Add(new Label($"{i}") { style = { fontSize = 9 } });
|
|
755
|
+
|
|
756
|
+
int currentIndex = i;
|
|
757
|
+
thumbContainer.userData = currentIndex;
|
|
758
|
+
|
|
759
|
+
thumbContainer.RegisterCallback<PointerDownEvent>(evt =>
|
|
760
|
+
{
|
|
761
|
+
if (evt.button == 0)
|
|
762
|
+
{
|
|
763
|
+
_isDraggingToSelectSprites = true;
|
|
764
|
+
_spriteSelectionDragStartIndex = currentIndex;
|
|
765
|
+
_spriteSelectionDragCurrentIndex = currentIndex;
|
|
766
|
+
UpdateSpriteSelectionHighlight();
|
|
767
|
+
|
|
768
|
+
_spriteThumbnailsContainer.CapturePointer(evt.pointerId);
|
|
769
|
+
evt.StopPropagation();
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
thumbContainer.RegisterCallback<PointerEnterEvent>(_ =>
|
|
774
|
+
{
|
|
775
|
+
if (
|
|
776
|
+
_isDraggingToSelectSprites
|
|
777
|
+
&& _spriteThumbnailsContainer.HasPointerCapture(PointerId.mousePointerId)
|
|
778
|
+
&& _spriteSelectionDragCurrentIndex != currentIndex
|
|
779
|
+
)
|
|
780
|
+
{
|
|
781
|
+
_spriteSelectionDragCurrentIndex = currentIndex;
|
|
782
|
+
UpdateSpriteSelectionHighlight();
|
|
783
|
+
}
|
|
784
|
+
});
|
|
553
785
|
_spriteThumbnailsContainer.Add(thumbContainer);
|
|
554
786
|
}
|
|
555
787
|
}
|
|
@@ -562,7 +794,7 @@
|
|
|
562
794
|
}
|
|
563
795
|
}
|
|
564
796
|
|
|
565
|
-
private VisualElement MakeAnimationDefinitionItem()
|
|
797
|
+
private static VisualElement MakeAnimationDefinitionItem()
|
|
566
798
|
{
|
|
567
799
|
VisualElement container = new()
|
|
568
800
|
{
|
|
@@ -597,6 +829,10 @@
|
|
|
597
829
|
{
|
|
598
830
|
style = { flexDirection = FlexDirection.Row, alignItems = Align.Center },
|
|
599
831
|
};
|
|
832
|
+
VisualElement fourthRow = new()
|
|
833
|
+
{
|
|
834
|
+
style = { flexDirection = FlexDirection.Row, alignItems = Align.Center },
|
|
835
|
+
};
|
|
600
836
|
|
|
601
837
|
TextField nameField = new("Name:")
|
|
602
838
|
{
|
|
@@ -657,9 +893,33 @@
|
|
|
657
893
|
thirdRow.Add(fpsField);
|
|
658
894
|
thirdRow.Add(curveField);
|
|
659
895
|
|
|
896
|
+
Toggle looping = new("Looping:")
|
|
897
|
+
{
|
|
898
|
+
style =
|
|
899
|
+
{
|
|
900
|
+
flexGrow = 1,
|
|
901
|
+
flexShrink = 1,
|
|
902
|
+
marginRight = 5,
|
|
903
|
+
},
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
FloatField cycleOffset = new("Cycle Offset:")
|
|
907
|
+
{
|
|
908
|
+
style =
|
|
909
|
+
{
|
|
910
|
+
flexGrow = 1,
|
|
911
|
+
flexShrink = 1,
|
|
912
|
+
marginRight = 5,
|
|
913
|
+
},
|
|
914
|
+
};
|
|
915
|
+
|
|
916
|
+
fourthRow.Add(looping);
|
|
917
|
+
fourthRow.Add(cycleOffset);
|
|
918
|
+
|
|
660
919
|
container.Add(firstRow);
|
|
661
920
|
container.Add(secondRow);
|
|
662
921
|
container.Add(thirdRow);
|
|
922
|
+
container.Add(fourthRow);
|
|
663
923
|
|
|
664
924
|
container.userData = new AnimationDefUITags
|
|
665
925
|
{
|
|
@@ -671,6 +931,8 @@
|
|
|
671
931
|
spriteCountLabel = spriteCountLabel,
|
|
672
932
|
previewButton = previewButton,
|
|
673
933
|
removeButton = removeButton,
|
|
934
|
+
looping = looping,
|
|
935
|
+
cycleOffset = cycleOffset,
|
|
674
936
|
};
|
|
675
937
|
return container;
|
|
676
938
|
}
|
|
@@ -685,11 +947,13 @@
|
|
|
685
947
|
public Label spriteCountLabel;
|
|
686
948
|
public Button previewButton;
|
|
687
949
|
public Button removeButton;
|
|
950
|
+
public Toggle looping;
|
|
951
|
+
public FloatField cycleOffset;
|
|
688
952
|
}
|
|
689
953
|
|
|
690
954
|
private void BindAnimationDefinitionItem(VisualElement element, int index)
|
|
691
955
|
{
|
|
692
|
-
AnimationDefinition
|
|
956
|
+
AnimationDefinition definition = _animationDefinitions[index];
|
|
693
957
|
if (element.userData is not AnimationDefUITags tags)
|
|
694
958
|
{
|
|
695
959
|
this.LogError(
|
|
@@ -698,143 +962,178 @@
|
|
|
698
962
|
return;
|
|
699
963
|
}
|
|
700
964
|
|
|
701
|
-
|
|
702
|
-
|
|
965
|
+
definition.nameField?.UnregisterValueChangedCallback(
|
|
966
|
+
definition.nameField.userData as EventCallback<ChangeEvent<string>>
|
|
703
967
|
);
|
|
704
968
|
|
|
705
|
-
|
|
706
|
-
|
|
969
|
+
definition.startIndexField?.UnregisterValueChangedCallback(
|
|
970
|
+
definition.startIndexField.userData as EventCallback<ChangeEvent<int>>
|
|
707
971
|
);
|
|
708
972
|
|
|
709
|
-
|
|
710
|
-
|
|
973
|
+
definition.endIndexField?.UnregisterValueChangedCallback(
|
|
974
|
+
definition.endIndexField.userData as EventCallback<ChangeEvent<int>>
|
|
711
975
|
);
|
|
712
976
|
|
|
713
|
-
|
|
714
|
-
|
|
977
|
+
definition.defaultFrameRateField?.UnregisterValueChangedCallback(
|
|
978
|
+
definition.defaultFrameRateField.userData as EventCallback<ChangeEvent<float>>
|
|
715
979
|
);
|
|
716
980
|
|
|
717
|
-
|
|
718
|
-
|
|
981
|
+
definition.frameRateCurveField?.UnregisterValueChangedCallback(
|
|
982
|
+
definition.frameRateCurveField.userData
|
|
983
|
+
as EventCallback<ChangeEvent<AnimationCurve>>
|
|
719
984
|
);
|
|
720
985
|
|
|
721
|
-
if (
|
|
986
|
+
if (definition.removeButton != null)
|
|
722
987
|
{
|
|
723
|
-
|
|
988
|
+
definition.removeButton.clicked -= (Action)definition.removeButton.userData;
|
|
724
989
|
}
|
|
725
990
|
|
|
726
|
-
if (
|
|
991
|
+
if (definition.previewButton != null)
|
|
727
992
|
{
|
|
728
|
-
|
|
993
|
+
definition.previewButton.clicked -= (Action)definition.previewButton.userData;
|
|
729
994
|
}
|
|
730
995
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
def.removeButton = tags.removeButton;
|
|
738
|
-
def.previewButton = tags.previewButton;
|
|
996
|
+
definition.loopingField?.UnregisterValueChangedCallback(
|
|
997
|
+
(EventCallback<ChangeEvent<bool>>)definition.loopingField.userData
|
|
998
|
+
);
|
|
999
|
+
definition.cycleOffsetField?.UnregisterValueChangedCallback(
|
|
1000
|
+
(EventCallback<ChangeEvent<float>>)definition.cycleOffsetField.userData
|
|
1001
|
+
);
|
|
739
1002
|
|
|
740
|
-
|
|
1003
|
+
definition.nameField = tags.nameField;
|
|
1004
|
+
definition.startIndexField = tags.startIndexField;
|
|
1005
|
+
definition.endIndexField = tags.endIndexField;
|
|
1006
|
+
definition.defaultFrameRateField = tags.defaultFrameRateField;
|
|
1007
|
+
definition.frameRateCurveField = tags.frameRateCurveField;
|
|
1008
|
+
definition.spriteCountLabel = tags.spriteCountLabel;
|
|
1009
|
+
definition.removeButton = tags.removeButton;
|
|
1010
|
+
definition.previewButton = tags.previewButton;
|
|
1011
|
+
definition.loopingField = tags.looping;
|
|
1012
|
+
definition.cycleOffsetField = tags.cycleOffset;
|
|
1013
|
+
|
|
1014
|
+
definition.nameField.SetValueWithoutNotify(definition.Name);
|
|
741
1015
|
EventCallback<ChangeEvent<string>> nameChangeCallback = evt =>
|
|
742
1016
|
{
|
|
743
|
-
|
|
1017
|
+
definition.Name = evt.newValue;
|
|
744
1018
|
};
|
|
745
|
-
|
|
746
|
-
|
|
1019
|
+
definition.nameField.RegisterValueChangedCallback(nameChangeCallback);
|
|
1020
|
+
definition.nameField.userData = nameChangeCallback;
|
|
747
1021
|
|
|
748
|
-
|
|
1022
|
+
definition.startIndexField.SetValueWithoutNotify(definition.StartSpriteIndex);
|
|
749
1023
|
EventCallback<ChangeEvent<int>> startChangeCallback = evt =>
|
|
750
1024
|
{
|
|
751
|
-
|
|
1025
|
+
definition.StartSpriteIndex = Mathf.Clamp(
|
|
752
1026
|
evt.newValue,
|
|
753
1027
|
0,
|
|
754
1028
|
_availableSprites.Count > 0 ? _availableSprites.Count - 1 : 0
|
|
755
1029
|
);
|
|
756
|
-
if (
|
|
1030
|
+
if (
|
|
1031
|
+
definition.StartSpriteIndex > definition.EndSpriteIndex
|
|
1032
|
+
&& 0 < _availableSprites.Count
|
|
1033
|
+
)
|
|
757
1034
|
{
|
|
758
|
-
|
|
1035
|
+
definition.EndSpriteIndex = definition.StartSpriteIndex;
|
|
759
1036
|
}
|
|
760
1037
|
|
|
761
|
-
|
|
762
|
-
UpdateSpritesForDefinition(
|
|
1038
|
+
definition.startIndexField.SetValueWithoutNotify(definition.StartSpriteIndex);
|
|
1039
|
+
UpdateSpritesForDefinition(definition);
|
|
763
1040
|
if (_currentPreviewAnimDefIndex == index)
|
|
764
1041
|
{
|
|
765
|
-
StartOrUpdateCurrentPreview(
|
|
1042
|
+
StartOrUpdateCurrentPreview(definition);
|
|
766
1043
|
}
|
|
767
1044
|
};
|
|
768
|
-
|
|
769
|
-
|
|
1045
|
+
definition.startIndexField.RegisterValueChangedCallback(startChangeCallback);
|
|
1046
|
+
definition.startIndexField.userData = startChangeCallback;
|
|
770
1047
|
|
|
771
|
-
|
|
1048
|
+
definition.endIndexField.SetValueWithoutNotify(definition.EndSpriteIndex);
|
|
772
1049
|
EventCallback<ChangeEvent<int>> endChangeCallback = evt =>
|
|
773
1050
|
{
|
|
774
|
-
|
|
1051
|
+
definition.EndSpriteIndex = Mathf.Clamp(
|
|
775
1052
|
evt.newValue,
|
|
776
1053
|
0,
|
|
777
1054
|
_availableSprites.Count > 0 ? _availableSprites.Count - 1 : 0
|
|
778
1055
|
);
|
|
779
|
-
if (
|
|
1056
|
+
if (
|
|
1057
|
+
definition.EndSpriteIndex < definition.StartSpriteIndex
|
|
1058
|
+
&& 0 < _availableSprites.Count
|
|
1059
|
+
)
|
|
780
1060
|
{
|
|
781
|
-
|
|
1061
|
+
definition.StartSpriteIndex = definition.EndSpriteIndex;
|
|
782
1062
|
}
|
|
783
1063
|
|
|
784
|
-
|
|
785
|
-
UpdateSpritesForDefinition(
|
|
1064
|
+
definition.endIndexField.SetValueWithoutNotify(definition.EndSpriteIndex);
|
|
1065
|
+
UpdateSpritesForDefinition(definition);
|
|
786
1066
|
if (_currentPreviewAnimDefIndex == index)
|
|
787
1067
|
{
|
|
788
|
-
StartOrUpdateCurrentPreview(
|
|
1068
|
+
StartOrUpdateCurrentPreview(definition);
|
|
789
1069
|
}
|
|
790
1070
|
};
|
|
791
|
-
|
|
792
|
-
|
|
1071
|
+
definition.endIndexField.RegisterValueChangedCallback(endChangeCallback);
|
|
1072
|
+
definition.endIndexField.userData = endChangeCallback;
|
|
793
1073
|
|
|
794
|
-
|
|
1074
|
+
definition.defaultFrameRateField.SetValueWithoutNotify(definition.DefaultFrameRate);
|
|
795
1075
|
EventCallback<ChangeEvent<float>> fpsChangeCallback = evt =>
|
|
796
1076
|
{
|
|
797
|
-
|
|
798
|
-
|
|
1077
|
+
definition.DefaultFrameRate = Mathf.Max(0.1f, evt.newValue);
|
|
1078
|
+
definition.defaultFrameRateField.SetValueWithoutNotify(definition.DefaultFrameRate);
|
|
799
1079
|
|
|
800
|
-
if (IsCurveConstant(
|
|
1080
|
+
if (IsCurveConstant(definition.FrameRateCurve))
|
|
801
1081
|
{
|
|
802
|
-
|
|
803
|
-
|
|
1082
|
+
definition.FrameRateCurve = AnimationCurve.Constant(
|
|
1083
|
+
0,
|
|
1084
|
+
1,
|
|
1085
|
+
definition.DefaultFrameRate
|
|
1086
|
+
);
|
|
1087
|
+
definition.frameRateCurveField.SetValueWithoutNotify(definition.FrameRateCurve);
|
|
804
1088
|
}
|
|
805
1089
|
if (_currentPreviewAnimDefIndex == index)
|
|
806
1090
|
{
|
|
807
|
-
StartOrUpdateCurrentPreview(
|
|
1091
|
+
StartOrUpdateCurrentPreview(definition);
|
|
808
1092
|
}
|
|
809
1093
|
};
|
|
810
|
-
|
|
811
|
-
|
|
1094
|
+
definition.defaultFrameRateField.RegisterValueChangedCallback(fpsChangeCallback);
|
|
1095
|
+
definition.defaultFrameRateField.userData = fpsChangeCallback;
|
|
812
1096
|
|
|
813
|
-
|
|
1097
|
+
definition.frameRateCurveField.SetValueWithoutNotify(definition.FrameRateCurve);
|
|
814
1098
|
EventCallback<ChangeEvent<AnimationCurve>> curveChangeCallback = evt =>
|
|
815
1099
|
{
|
|
816
|
-
|
|
1100
|
+
definition.FrameRateCurve = evt.newValue;
|
|
817
1101
|
if (_currentPreviewAnimDefIndex == index)
|
|
818
1102
|
{
|
|
819
|
-
StartOrUpdateCurrentPreview(
|
|
1103
|
+
StartOrUpdateCurrentPreview(definition);
|
|
820
1104
|
}
|
|
821
1105
|
};
|
|
822
|
-
|
|
823
|
-
|
|
1106
|
+
definition.frameRateCurveField.RegisterValueChangedCallback(curveChangeCallback);
|
|
1107
|
+
definition.frameRateCurveField.userData = curveChangeCallback;
|
|
824
1108
|
|
|
825
1109
|
Action removeAction = () => RemoveAnimationDefinition(index);
|
|
826
|
-
|
|
827
|
-
|
|
1110
|
+
definition.removeButton.clicked += removeAction;
|
|
1111
|
+
definition.removeButton.userData = removeAction;
|
|
828
1112
|
|
|
829
1113
|
Action previewAction = () =>
|
|
830
1114
|
{
|
|
831
1115
|
_currentPreviewAnimDefIndex = index;
|
|
832
|
-
StartOrUpdateCurrentPreview(
|
|
1116
|
+
StartOrUpdateCurrentPreview(definition);
|
|
1117
|
+
};
|
|
1118
|
+
definition.previewButton.clicked += previewAction;
|
|
1119
|
+
definition.previewButton.userData = previewAction;
|
|
1120
|
+
|
|
1121
|
+
EventCallback<ChangeEvent<bool>> loopingChangeCallback = evt =>
|
|
1122
|
+
{
|
|
1123
|
+
definition.loop = evt.newValue;
|
|
833
1124
|
};
|
|
834
|
-
def.previewButton.clicked += previewAction;
|
|
835
|
-
def.previewButton.userData = previewAction;
|
|
836
1125
|
|
|
837
|
-
|
|
1126
|
+
definition.loopingField.RegisterValueChangedCallback(loopingChangeCallback);
|
|
1127
|
+
definition.loopingField.userData = loopingChangeCallback;
|
|
1128
|
+
|
|
1129
|
+
EventCallback<ChangeEvent<float>> cycleOffsetChangeCallback = evt =>
|
|
1130
|
+
{
|
|
1131
|
+
definition.cycleOffset = evt.newValue;
|
|
1132
|
+
};
|
|
1133
|
+
definition.cycleOffsetField.RegisterValueChangedCallback(cycleOffsetChangeCallback);
|
|
1134
|
+
definition.cycleOffsetField.userData = cycleOffsetChangeCallback;
|
|
1135
|
+
|
|
1136
|
+
UpdateSpritesForDefinition(definition);
|
|
838
1137
|
}
|
|
839
1138
|
|
|
840
1139
|
private static bool IsCurveConstant(AnimationCurve curve)
|
|
@@ -887,6 +1186,16 @@
|
|
|
887
1186
|
}
|
|
888
1187
|
if (0 < _availableSprites.Count)
|
|
889
1188
|
{
|
|
1189
|
+
if (0 < _animationDefinitions.Count)
|
|
1190
|
+
{
|
|
1191
|
+
int nextStartIndex = _animationDefinitions[^1].EndSpriteIndex + 1;
|
|
1192
|
+
if (_availableSprites.Count - 1 <= nextStartIndex)
|
|
1193
|
+
{
|
|
1194
|
+
nextStartIndex = 0;
|
|
1195
|
+
}
|
|
1196
|
+
newDef.StartSpriteIndex = nextStartIndex;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
890
1199
|
newDef.EndSpriteIndex = _availableSprites.Count - 1;
|
|
891
1200
|
}
|
|
892
1201
|
newDef.FrameRateCurve = AnimationCurve.Constant(0, 1, newDef.DefaultFrameRate);
|
|
@@ -1068,12 +1377,17 @@
|
|
|
1068
1377
|
Directory.CreateDirectory(animationsFolder);
|
|
1069
1378
|
}
|
|
1070
1379
|
|
|
1380
|
+
if (!animationsFolder.StartsWith("Assets", StringComparison.OrdinalIgnoreCase))
|
|
1381
|
+
{
|
|
1382
|
+
animationsFolder = DirectoryHelper.AbsoluteToUnityRelativePath(animationsFolder);
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1071
1385
|
int createdCount = 0;
|
|
1072
|
-
foreach (AnimationDefinition
|
|
1386
|
+
foreach (AnimationDefinition definition in _animationDefinitions)
|
|
1073
1387
|
{
|
|
1074
|
-
if (
|
|
1388
|
+
if (definition.SpritesToAnimate.Count == 0)
|
|
1075
1389
|
{
|
|
1076
|
-
|
|
1390
|
+
this.LogWarn($"Skipping animation '{definition.Name}' as it has no sprites.");
|
|
1077
1391
|
continue;
|
|
1078
1392
|
}
|
|
1079
1393
|
|
|
@@ -1087,21 +1401,21 @@
|
|
|
1087
1401
|
};
|
|
1088
1402
|
|
|
1089
1403
|
ObjectReferenceKeyframe[] keyframes = new ObjectReferenceKeyframe[
|
|
1090
|
-
|
|
1404
|
+
definition.SpritesToAnimate.Count
|
|
1091
1405
|
];
|
|
1092
1406
|
float currentTime = 0f;
|
|
1093
|
-
AnimationCurve curve =
|
|
1407
|
+
AnimationCurve curve = definition.FrameRateCurve;
|
|
1094
1408
|
if (curve == null || curve.keys.Length == 0)
|
|
1095
1409
|
{
|
|
1096
|
-
|
|
1097
|
-
$"Animation '{
|
|
1410
|
+
this.LogWarn(
|
|
1411
|
+
$"Animation '{definition.Name}' has an invalid FrameRateCurve. Falling back to DefaultFrameRate."
|
|
1098
1412
|
);
|
|
1099
|
-
curve = AnimationCurve.Constant(0, 1,
|
|
1413
|
+
curve = AnimationCurve.Constant(0, 1, definition.DefaultFrameRate);
|
|
1100
1414
|
}
|
|
1101
1415
|
|
|
1102
1416
|
if (curve.keys.Length == 0)
|
|
1103
1417
|
{
|
|
1104
|
-
curve.AddKey(0,
|
|
1418
|
+
curve.AddKey(0, definition.DefaultFrameRate);
|
|
1105
1419
|
}
|
|
1106
1420
|
|
|
1107
1421
|
float curveDuration = curve.keys.LastOrDefault().time;
|
|
@@ -1110,26 +1424,26 @@
|
|
|
1110
1424
|
curveDuration = 1f;
|
|
1111
1425
|
}
|
|
1112
1426
|
|
|
1113
|
-
for (int i = 0; i <
|
|
1427
|
+
for (int i = 0; i < definition.SpritesToAnimate.Count; ++i)
|
|
1114
1428
|
{
|
|
1115
1429
|
keyframes[i] = new ObjectReferenceKeyframe
|
|
1116
1430
|
{
|
|
1117
1431
|
time = currentTime,
|
|
1118
|
-
value =
|
|
1432
|
+
value = definition.SpritesToAnimate[i],
|
|
1119
1433
|
};
|
|
1120
1434
|
|
|
1121
|
-
if (i <
|
|
1435
|
+
if (i < definition.SpritesToAnimate.Count - 1)
|
|
1122
1436
|
{
|
|
1123
1437
|
float normalizedTimeForCurve =
|
|
1124
|
-
|
|
1125
|
-
? (float)i / (
|
|
1438
|
+
definition.SpritesToAnimate.Count > 1
|
|
1439
|
+
? (float)i / (definition.SpritesToAnimate.Count - 1)
|
|
1126
1440
|
: 0;
|
|
1127
1441
|
float timeForCurveEval = normalizedTimeForCurve * curveDuration;
|
|
1128
1442
|
|
|
1129
1443
|
float fps = curve.Evaluate(timeForCurveEval);
|
|
1130
1444
|
if (fps <= 0)
|
|
1131
1445
|
{
|
|
1132
|
-
fps =
|
|
1446
|
+
fps = definition.DefaultFrameRate;
|
|
1133
1447
|
}
|
|
1134
1448
|
|
|
1135
1449
|
if (fps <= 0)
|
|
@@ -1144,15 +1458,16 @@
|
|
|
1144
1458
|
AnimationUtility.SetObjectReferenceCurve(clip, spriteBinding, keyframes);
|
|
1145
1459
|
|
|
1146
1460
|
AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(clip);
|
|
1147
|
-
settings.loopTime =
|
|
1461
|
+
settings.loopTime = definition.loop;
|
|
1462
|
+
settings.cycleOffset = definition.cycleOffset;
|
|
1148
1463
|
AnimationUtility.SetAnimationClipSettings(clip, settings);
|
|
1149
1464
|
|
|
1150
|
-
string animName = string.IsNullOrEmpty(
|
|
1465
|
+
string animName = string.IsNullOrEmpty(definition.Name)
|
|
1466
|
+
? "UnnamedAnim"
|
|
1467
|
+
: definition.Name;
|
|
1151
1468
|
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
animName = animName.Replace(character, '_');
|
|
1155
|
-
}
|
|
1469
|
+
animName = Path.GetInvalidFileNameChars()
|
|
1470
|
+
.Aggregate(animName, (current, character) => current.Replace(character, '_'));
|
|
1156
1471
|
string assetPath = Path.Combine(animationsFolder, $"{animName}.anim");
|
|
1157
1472
|
assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath);
|
|
1158
1473
|
|
|
@@ -1169,9 +1484,6 @@
|
|
|
1169
1484
|
$"{createdCount} animation(s) created in:\n{animationsFolder}",
|
|
1170
1485
|
"OK"
|
|
1171
1486
|
);
|
|
1172
|
-
EditorGUIUtility.PingObject(
|
|
1173
|
-
AssetDatabase.LoadAssetAtPath<Object>(animationsFolder)
|
|
1174
|
-
);
|
|
1175
1487
|
}
|
|
1176
1488
|
else
|
|
1177
1489
|
{
|