以下是实现你需求的Unity编辑器脚本。该脚本会自动创建两个GameObject(ObjectA和ObjectB),添加SpriteRenderer组件,并生成包含指定关键帧动画的AnimationClip。
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
public class AnimationGenerator : EditorWindow
{
[MenuItem("Tools/Generate Animation")]
static void GenerateAnimation()
{
// 创建或获取物体
GameObject objA = GetOrCreateObject("ObjectA");
GameObject objB = GetOrCreateObject("ObjectB");
// 加载Sprite资源(需要根据实际路径修改)
string pathA = "Assets/Sprites/A";
string pathB = "Assets/Sprites/B";
List<Sprite> aSprites = LoadSprites(pathA);
List<Sprite> bSprites = LoadSprites(pathB);
int totalPairs = Mathf.Min(aSprites.Count, bSprites.Count);
if (totalPairs == 0)
{
Debug.LogError("No sprites found!");
return;
}
// 创建AnimationClip
AnimationClip clip = new AnimationClip();
clip.frameRate = 60;
clip.name = "GeneratedAnimation";
// 获取物体路径
string aPath = AnimationUtility.CalculateTransformPath(objA.transform, null);
string bPath = AnimationUtility.CalculateTransformPath(objB.transform, null);
// 初始化曲线数据
var aActive = new AnimationCurve();
var bActive = new AnimationCurve();
var aSpritesKeys = new List<ObjectReferenceKeyframe>();
var bSpritesKeys = new List<ObjectReferenceKeyframe>();
// 生成关键帧
for (int i = 0; i < totalPairs; i++)
{
int baseFrame = i * 180;
float baseTime = baseFrame / 60f;
// 添加Sprite关键帧
aSpritesKeys.Add(new ObjectReferenceKeyframe { time = baseTime, value = aSprites[i] });
bSpritesKeys.Add(new ObjectReferenceKeyframe { time = baseTime, value = bSprites[i] });
// 生成每个周期内的6个关键点(0,30,60,90,120,150)
for (int j = 0; j < 6; j++)
{
int frame = baseFrame + j * 30;
float time = frame / 60f;
bool isA = j % 2 == 0;
aActive.AddKey(time, isA ? 1f : 0f);
bActive.AddKey(time, isA ? 0f : 1f);
}
}
// 设置动画曲线
SetCurve(clip, aPath, "m_IsActive", aActive);
SetCurve(clip, bPath, "m_IsActive", bActive);
SetObjectCurve(clip, aPath, "m_Sprite", aSpritesKeys.ToArray());
SetObjectCurve(clip, bPath, "m_Sprite", bSpritesKeys.ToArray());
// 保存资源
AssetDatabase.CreateAsset(clip, "Assets/GeneratedAnimation.anim");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
static GameObject GetOrCreateObject(string name)
{
GameObject obj = GameObject.Find(name);
if (!obj)
{
obj = new GameObject(name);
obj.AddComponent<SpriteRenderer>();
}
return obj;
}
static List<Sprite> LoadSprites(string path)
{
List<Sprite> sprites = new List<Sprite>();
string[] guids = AssetDatabase.FindAssets("t:Sprite", new[] { path });
foreach (string guid in guids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(assetPath);
if (sprite) sprites.Add(sprite);
}
sprites.Sort((a, b) => a.name.CompareTo(b.name));
return sprites;
}
static void SetCurve(AnimationClip clip, string path, string property, AnimationCurve curve)
{
EditorCurveBinding binding = new EditorCurveBinding
{
path = path,
type = typeof(GameObject),
propertyName = property
};
AnimationUtility.SetEditorCurve(clip, binding, curve);
}
static void SetObjectCurve(AnimationClip clip, string path, string property, ObjectReferenceKeyframe[] keys)
{
EditorCurveBinding binding = new EditorCurveBinding
{
path = path,
type = typeof(SpriteRenderer),
propertyName = property
};
AnimationUtility.SetObjectReferenceCurve(clip, binding, keys);
}
}
使用说明:
- 在Project窗口创建Editor文件夹(如果不存在)
- 创建新C#脚本,命名为AnimationGenerator,替换内容为上述代码
- 在Assets目录下创建两个文件夹:
- Assets/Sprites/A(存放a1, a2, a3…等Sprite)
- Assets/Sprites/B(存放b1, b2, b3…等Sprite)
- 通过菜单栏 Tools > Generate Animation 执行脚本
功能说明:
- 自动创建ObjectA和ObjectB并添加SpriteRenderer
- 每3秒(180帧)切换一次Sprite
- 每个Sprite会以1秒(30帧)间隔切换显示三次
- 生成的动画文件保存为Assets/GeneratedAnimation.anim
注意:
- Sprite需要按名称排序(如a1、a2…)
- A、B文件夹内的Sprite数量应该相同
- 需要Unity 2022.3.51或更新版本
- 动画总时长 = 3秒 × Sprite数量
- 最终生成的动画需要手动添加到Animator中使用
你可以通过Animation窗口查看生成的动画曲线,并根据需要调整时间间隔或Sprite路径。