沙雕动画表情切换:Unity Editor脚本。这个脚本将会在编辑器中创建一个父物体,并为其添加动画控制器。然后创建两个子物体,添加SpriteRenderer组件,并设置关键帧动画。

以下是实现你需求的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);
    }
}

使用说明:

  1. 在Project窗口创建Editor文件夹(如果不存在)
  2. 创建新C#脚本,命名为AnimationGenerator,替换内容为上述代码
  3. 在Assets目录下创建两个文件夹:
    • Assets/Sprites/A(存放a1, a2, a3…等Sprite)
    • Assets/Sprites/B(存放b1, b2, b3…等Sprite)
  4. 通过菜单栏 Tools > Generate Animation 执行脚本

功能说明:

  • 自动创建ObjectA和ObjectB并添加SpriteRenderer
  • 每3秒(180帧)切换一次Sprite
  • 每个Sprite会以1秒(30帧)间隔切换显示三次
  • 生成的动画文件保存为Assets/GeneratedAnimation.anim

注意:

  1. Sprite需要按名称排序(如a1、a2…)
  2. A、B文件夹内的Sprite数量应该相同
  3. 需要Unity 2022.3.51或更新版本
  4. 动画总时长 = 3秒 × Sprite数量
  5. 最终生成的动画需要手动添加到Animator中使用

你可以通过Animation窗口查看生成的动画曲线,并根据需要调整时间间隔或Sprite路径。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值