208 lines
8.2 KiB
C#
208 lines
8.2 KiB
C#
using System.IO;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.SystemEditor
|
|
{
|
|
public class AnimationClipGenerator : EditorWindow
|
|
{
|
|
private Texture2D selectedTexture;
|
|
private TextAsset selectedJson;
|
|
private DefaultAsset outputFolder;
|
|
private string outputPath = "";
|
|
|
|
// 动画类型选项
|
|
private enum AnimationTargetType
|
|
{
|
|
SpriteRenderer, // Sprite动画
|
|
Image // UIImage动画
|
|
}
|
|
private AnimationTargetType animationType = AnimationTargetType.SpriteRenderer;
|
|
|
|
// Pivot 设置选项
|
|
private enum PivotAlignment
|
|
{
|
|
Center, // 中心 (0.5, 0.5)
|
|
TopLeft, // 左上 (0, 1)
|
|
TopRight, // 右上 (1, 1)
|
|
BottomLeft, // 左下 (0, 0)
|
|
BottomRight, // 右下 (1, 0)
|
|
TopCenter, // 上中 (0.5, 1)
|
|
BottomCenter, // 下中 (0.5, 0)
|
|
LeftCenter, // 左中 (0, 0.5)
|
|
RightCenter, // 右中 (1, 0.5)
|
|
Custom // 自定义
|
|
}
|
|
private PivotAlignment pivotAlignment = PivotAlignment.Center;
|
|
private Vector2 customPivot = new Vector2(0.5f, 0.5f);
|
|
|
|
[MenuItem(AibisEditorMenus.AnimationClipGenerator)]
|
|
public static void ShowWindow()
|
|
{
|
|
GetWindow<AnimationClipGenerator>("动画片段生成器(Animation Clip Generator)");
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
// 图片文件选择
|
|
EditorGUILayout.LabelField("图片文件 (PNG/JPG)", EditorStyles.boldLabel);
|
|
selectedTexture = (Texture2D)EditorGUILayout.ObjectField(
|
|
"Texture", selectedTexture, typeof(Texture2D), false);
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
// JSON文件选择
|
|
EditorGUILayout.LabelField("JSON文件", EditorStyles.boldLabel);
|
|
selectedJson = (TextAsset)EditorGUILayout.ObjectField(
|
|
"JSON", selectedJson, typeof(TextAsset), false);
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
// 动画类型选择
|
|
EditorGUILayout.LabelField("动画类型", EditorStyles.boldLabel);
|
|
animationType = (AnimationTargetType)EditorGUILayout.EnumPopup(
|
|
"Animation Type", animationType);
|
|
EditorGUILayout.HelpBox(
|
|
animationType == AnimationTargetType.SpriteRenderer
|
|
? "生成用于SpriteRenderer的动画(绑定到m_Sprite属性)"
|
|
: "生成用于Unity UI Image的动画(绑定到m_Sprite属性)",
|
|
MessageType.Info);
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
// Pivot 设置
|
|
EditorGUILayout.LabelField("Pivot 设置", EditorStyles.boldLabel);
|
|
pivotAlignment = (PivotAlignment)EditorGUILayout.EnumPopup(
|
|
"Pivot Alignment", pivotAlignment);
|
|
|
|
if (pivotAlignment == PivotAlignment.Custom)
|
|
{
|
|
customPivot = EditorGUILayout.Vector2Field("Custom Pivot", customPivot);
|
|
// 限制 pivot 值在 0-1 范围内
|
|
customPivot.x = Mathf.Clamp01(customPivot.x);
|
|
customPivot.y = Mathf.Clamp01(customPivot.y);
|
|
EditorGUILayout.HelpBox(
|
|
"自定义 Pivot 值范围: X 和 Y 应在 0-1 之间\n" +
|
|
"例如: (0, 0) = 左下角, (0.5, 0.5) = 中心, (1, 1) = 右上角",
|
|
MessageType.Info);
|
|
}
|
|
else
|
|
{
|
|
Vector2 previewPivot = GetPivotFromAlignment(pivotAlignment);
|
|
EditorGUILayout.HelpBox(
|
|
$"当前 Pivot: ({previewPivot.x:F2}, {previewPivot.y:F2})",
|
|
MessageType.Info);
|
|
}
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
// 输出目录选择
|
|
EditorGUILayout.LabelField("输出目录", EditorStyles.boldLabel);
|
|
outputFolder = (DefaultAsset)EditorGUILayout.ObjectField(
|
|
"Output Folder", outputFolder, typeof(DefaultAsset), false);
|
|
|
|
// 显示输出路径
|
|
if (outputFolder != null)
|
|
{
|
|
outputPath = AssetDatabase.GetAssetPath(outputFolder);
|
|
EditorGUILayout.HelpBox($"输出路径: {outputPath}", MessageType.Info);
|
|
}
|
|
else
|
|
{
|
|
outputPath = "";
|
|
}
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
// 生成按钮
|
|
GUI.enabled = selectedTexture != null && selectedJson != null && outputFolder != null;
|
|
if (GUILayout.Button("生成 AnimationClip", GUILayout.Height(30)))
|
|
{
|
|
GenerateAnimationClips();
|
|
}
|
|
GUI.enabled = true;
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
// 说明信息
|
|
EditorGUILayout.HelpBox(
|
|
"使用说明:\n" +
|
|
"1. 选择PNG或JPG图片文件\n" +
|
|
"2. 选择JSON文件(Aseprite格式或手动格式)\n" +
|
|
"3. 选择输出目录\n" +
|
|
"4. 点击生成按钮\n\n" +
|
|
"注意: 如果图片的SpriteMode是Single,工具会自动根据JSON切图。",
|
|
MessageType.Info);
|
|
}
|
|
|
|
private void GenerateAnimationClips()
|
|
{
|
|
if (selectedTexture == null || selectedJson == null || outputFolder == null)
|
|
{
|
|
EditorUtility.DisplayDialog("错误", "请选择图片文件、JSON文件和输出目录", "确定");
|
|
return;
|
|
}
|
|
|
|
string texturePath = AssetDatabase.GetAssetPath(selectedTexture);
|
|
string jsonPath = AssetDatabase.GetAssetPath(selectedJson);
|
|
|
|
// 验证文件扩展名
|
|
string textureExt = Path.GetExtension(texturePath).ToLower();
|
|
if (textureExt != ".png" && textureExt != ".jpg" && textureExt != ".jpeg")
|
|
{
|
|
EditorUtility.DisplayDialog("错误", "图片文件必须是PNG或JPG格式", "确定");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
bool isImageAnimation = animationType == AnimationTargetType.Image;
|
|
Vector2 pivot = pivotAlignment == PivotAlignment.Custom
|
|
? customPivot
|
|
: GetPivotFromAlignment(pivotAlignment);
|
|
// 确保 pivot 值在有效范围内
|
|
pivot.x = Mathf.Clamp01(pivot.x);
|
|
pivot.y = Mathf.Clamp01(pivot.y);
|
|
AnimationClipGeneratorCore.GenerateClips(texturePath, jsonPath, outputPath, isImageAnimation, pivot);
|
|
EditorUtility.DisplayDialog("成功", $"AnimationClip已生成到: {outputPath}", "确定");
|
|
|
|
// 刷新资源数据库
|
|
AssetDatabase.Refresh();
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
EditorUtility.DisplayDialog("错误", $"生成失败: {e.Message}", "确定");
|
|
Debug.LogError(e);
|
|
}
|
|
}
|
|
|
|
private Vector2 GetPivotFromAlignment(PivotAlignment alignment)
|
|
{
|
|
switch (alignment)
|
|
{
|
|
case PivotAlignment.Center:
|
|
return new Vector2(0.5f, 0.5f);
|
|
case PivotAlignment.TopLeft:
|
|
return new Vector2(0f, 1f);
|
|
case PivotAlignment.TopRight:
|
|
return new Vector2(1f, 1f);
|
|
case PivotAlignment.BottomLeft:
|
|
return new Vector2(0f, 0f);
|
|
case PivotAlignment.BottomRight:
|
|
return new Vector2(1f, 0f);
|
|
case PivotAlignment.TopCenter:
|
|
return new Vector2(0.5f, 1f);
|
|
case PivotAlignment.BottomCenter:
|
|
return new Vector2(0.5f, 0f);
|
|
case PivotAlignment.LeftCenter:
|
|
return new Vector2(0f, 0.5f);
|
|
case PivotAlignment.RightCenter:
|
|
return new Vector2(1f, 0.5f);
|
|
case PivotAlignment.Custom:
|
|
return customPivot;
|
|
default:
|
|
return new Vector2(0.5f, 0.5f);
|
|
}
|
|
}
|
|
}
|
|
} |