feat: 帧动画系统Timeline兼容
This commit is contained in:
@@ -10,6 +10,36 @@ using UnityEngine;
|
||||
|
||||
namespace AibisDream.FrameAnimation.Editor
|
||||
{
|
||||
internal readonly struct FrameAnimationSpriteSourceContext
|
||||
{
|
||||
public string SourceId { get; }
|
||||
public Texture2D Texture { get; }
|
||||
public TextAsset AsepriteJson { get; }
|
||||
public Vector2 Pivot { get; }
|
||||
public bool ManageSpriteSlicing { get; }
|
||||
|
||||
public FrameAnimationSpriteSourceContext(
|
||||
string sourceId,
|
||||
Texture2D texture,
|
||||
TextAsset asepriteJson,
|
||||
Vector2 pivot,
|
||||
bool manageSpriteSlicing)
|
||||
{
|
||||
SourceId = sourceId ?? string.Empty;
|
||||
Texture = texture;
|
||||
AsepriteJson = asepriteJson;
|
||||
Pivot = pivot;
|
||||
ManageSpriteSlicing = manageSpriteSlicing;
|
||||
}
|
||||
|
||||
public static FrameAnimationSpriteSourceContext From(FrameAnimationImportSource source)
|
||||
{
|
||||
return new FrameAnimationSpriteSourceContext(
|
||||
source?.InternalId, source?.Texture, source?.AsepriteJson,
|
||||
source?.Pivot ?? new Vector2(0.5f, 0.5f), source?.ManageSpriteSlicing == true);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class FrameAnimationSpritePlan
|
||||
{
|
||||
public string TexturePath { get; }
|
||||
@@ -91,6 +121,15 @@ namespace AibisDream.FrameAnimation.Editor
|
||||
FrameAnimationImportSource source,
|
||||
AsepriteSourceDocument document,
|
||||
FrameAnimationImportSourcePreview preview)
|
||||
{
|
||||
return BuildPlan(FrameAnimationSpriteSourceContext.From(source), document, preview);
|
||||
}
|
||||
|
||||
public static FrameAnimationSpritePlan BuildPlan(
|
||||
FrameAnimationSpriteSourceContext source,
|
||||
AsepriteSourceDocument document,
|
||||
IFrameAnimationImportPreviewSink preview,
|
||||
IReadOnlyCollection<int> includedSourceIndices = null)
|
||||
{
|
||||
var texturePath = AssetDatabase.GetAssetPath(source.Texture);
|
||||
var importer = AssetImporter.GetAtPath(texturePath) as TextureImporter;
|
||||
@@ -105,8 +144,8 @@ namespace AibisDream.FrameAnimation.Editor
|
||||
? Array.Empty<SpriteRect>()
|
||||
: ReadSpriteRects(importer);
|
||||
return source.ManageSpriteSlicing
|
||||
? BuildWritablePlan(source, document, preview, texturePath, existingRects)
|
||||
: BuildReadOnlyPlan(source, document, preview, texturePath, existingRects);
|
||||
? BuildWritablePlan(source, document, preview, texturePath, existingRects, includedSourceIndices)
|
||||
: BuildReadOnlyPlan(source, document, preview, texturePath, existingRects, includedSourceIndices);
|
||||
}
|
||||
|
||||
public static Rect ToUnityRect(RectInt asepriteRect, int textureHeight)
|
||||
@@ -175,7 +214,14 @@ namespace AibisDream.FrameAnimation.Editor
|
||||
FrameAnimationImportSource source,
|
||||
IReadOnlyList<SpriteRect> spriteRects = null)
|
||||
{
|
||||
if (source == null || source.Texture == null || source.AsepriteJson == null)
|
||||
return ComputeSourceHash(FrameAnimationSpriteSourceContext.From(source), spriteRects);
|
||||
}
|
||||
|
||||
public static string ComputeSourceHash(
|
||||
FrameAnimationSpriteSourceContext source,
|
||||
IReadOnlyList<SpriteRect> spriteRects = null)
|
||||
{
|
||||
if (source.Texture == null || source.AsepriteJson == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
@@ -214,17 +260,18 @@ namespace AibisDream.FrameAnimation.Editor
|
||||
}
|
||||
|
||||
private static FrameAnimationSpritePlan BuildWritablePlan(
|
||||
FrameAnimationImportSource source,
|
||||
FrameAnimationSpriteSourceContext source,
|
||||
AsepriteSourceDocument document,
|
||||
FrameAnimationImportSourcePreview preview,
|
||||
IFrameAnimationImportPreviewSink preview,
|
||||
string texturePath,
|
||||
IReadOnlyList<SpriteRect> existingRects)
|
||||
IReadOnlyList<SpriteRect> existingRects,
|
||||
IReadOnlyCollection<int> includedSourceIndices)
|
||||
{
|
||||
var planned = CloneRects(existingRects).ToList();
|
||||
var originalRects = planned.ToArray();
|
||||
var assigned = new HashSet<SpriteRect>();
|
||||
var spriteNamesBySourceIndex = new Dictionary<int, string>();
|
||||
foreach (var slot in document.SpriteSlots)
|
||||
foreach (var slot in EnumerateSlots(document, includedSourceIndices))
|
||||
{
|
||||
var unityRect = ToUnityRect(slot.Rect, source.Texture.height);
|
||||
SpriteRect matched = null;
|
||||
@@ -331,15 +378,16 @@ namespace AibisDream.FrameAnimation.Editor
|
||||
}
|
||||
|
||||
private static FrameAnimationSpritePlan BuildReadOnlyPlan(
|
||||
FrameAnimationImportSource source,
|
||||
FrameAnimationSpriteSourceContext source,
|
||||
AsepriteSourceDocument document,
|
||||
FrameAnimationImportSourcePreview preview,
|
||||
IFrameAnimationImportPreviewSink preview,
|
||||
string texturePath,
|
||||
IReadOnlyList<SpriteRect> existingRects)
|
||||
IReadOnlyList<SpriteRect> existingRects,
|
||||
IReadOnlyCollection<int> includedSourceIndices)
|
||||
{
|
||||
var sprites = AssetDatabase.LoadAllAssetsAtPath(texturePath).OfType<Sprite>().ToArray();
|
||||
var matches = new Dictionary<int, Sprite>();
|
||||
foreach (var slot in document.SpriteSlots)
|
||||
foreach (var slot in EnumerateSlots(document, includedSourceIndices))
|
||||
{
|
||||
var unityRect = ToUnityRect(slot.Rect, source.Texture.height);
|
||||
var rectMatches = sprites.Where(sprite => RectEquals(sprite.rect, unityRect)).ToArray();
|
||||
@@ -382,6 +430,32 @@ namespace AibisDream.FrameAnimation.Editor
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<AsepriteSpriteSlot> EnumerateSlots(
|
||||
AsepriteSourceDocument document,
|
||||
IReadOnlyCollection<int> includedSourceIndices)
|
||||
{
|
||||
if (includedSourceIndices == null)
|
||||
{
|
||||
return document.SpriteSlots;
|
||||
}
|
||||
|
||||
var included = new HashSet<int>(includedSourceIndices);
|
||||
return document.SpriteSlots.Select(slot =>
|
||||
{
|
||||
var indices = new List<int>();
|
||||
var names = new List<string>();
|
||||
for (var index = 0; index < slot.SourceIndices.Count; index++)
|
||||
{
|
||||
if (!included.Contains(slot.SourceIndices[index])) continue;
|
||||
indices.Add(slot.SourceIndices[index]);
|
||||
names.Add(slot.FrameNames[index]);
|
||||
}
|
||||
return indices.Count == 0
|
||||
? null
|
||||
: new AsepriteSpriteSlot(slot.Rect, names[0], indices, names);
|
||||
}).Where(slot => slot != null);
|
||||
}
|
||||
|
||||
private static string BuildSlotSummary(string prefix, AsepriteSpriteSlot slot)
|
||||
{
|
||||
return slot.SourceIndices.Count > 1
|
||||
@@ -440,15 +514,15 @@ namespace AibisDream.FrameAnimation.Editor
|
||||
}
|
||||
|
||||
private static FrameAnimationImportIssue Error(
|
||||
FrameAnimationImportSource source,
|
||||
FrameAnimationSpriteSourceContext source,
|
||||
FrameAnimationImportIssueCode code,
|
||||
string message)
|
||||
{
|
||||
return new FrameAnimationImportIssue(
|
||||
FrameAnimationValidationSeverity.Error,
|
||||
code,
|
||||
source?.InternalId,
|
||||
source?.InternalId,
|
||||
source.SourceId,
|
||||
source.SourceId,
|
||||
message);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user