一键自动状态机复用

@一键自动状态机复用

代码块

using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;

public class ImportAnimConWindow : EditorWindow
{
    string animConPath;         //需要复制动画状态机的位置
    string animClipPath;        //动画片段的位置
    static ImportAnimConWindow myWindow;
    static Dictionary<string, ImportAnimConClass> AllState = new Dictionary<string, ImportAnimConClass>();

    [@MenuItem("ProjectC/ImportAnimConWindow", false, 14)]
    private static void Open()
    {
        myWindow = GetWindow<ImportAnimConWindow>();
        myWindow.Show();
    }

    private void OnGUI()
    {
        animConPath = EditorGUILayout.TextField("动画状态机位置:", animConPath);
        if (GUILayout.Button("选择动画状态机相对位置", GUILayout.Width(160)))
        {
            var targetDir = new DirectoryInfo(string.Format(Application.dataPath + @"\Anim")); //相对与Assets的相对路径
            string path1 = EditorUtility.OpenFilePanel("选择需要生成的动画", targetDir.FullName.Replace("\\", "/"), "controller"); //选择.controller 文件
            if (string.IsNullOrEmpty(path1))
                return;
            animConPath = path1;
        }
        animClipPath = EditorGUILayout.TextField("动画片段位置:", animClipPath);
        if (GUILayout.Button("选择动画片段位置", GUILayout.Width(160)))
        {
            var targetDir = new DirectoryInfo(string.Format(Application.dataPath + @"\Anim"));//相对与Assets的相对路径
            string path1 = EditorUtility.OpenFolderPanel("Load Folder", targetDir.FullName.Replace("\\", "/"), "选择动画片段");//选择文件夹文件
            if (string.IsNullOrEmpty(path1))
                return;
            animClipPath = path1;
        }

        if (GUILayout.Button("生成动画状态机"))
        {
            Debug.LogError("点击生成动画状态机");
            if (animConPath == null || animClipPath == null)
            {
                Debug.LogError("请填充相对应的位置");
                return;
            }
            //获取新动画放置目录
            var targetDir = new DirectoryInfo(string.Format(@"{0}\..\", animClipPath));  //获取动画片段同目录下
            string animConFullPath = animConPath.Substring(animConPath.IndexOf("Assets/"));
            string[] fullNum1 = animConFullPath.Split('/');
            string[] half_Name = fullNum1[fullNum1.Length - 1].Split('_');
            //AnimatorController animationClip = (AnimatorController)AssetDatabase.LoadAssetAtPath(animConFullPath, typeof(AnimatorController));
            string copyPath = string.Format(@"{0}{1}_{2}", targetDir.FullName, targetDir.Name, half_Name[half_Name.Length - 1]);//生成的新的动画状态机位置名字
            File.Copy(animConPath, copyPath, true);  //复制并移动新的目录下
            AssetDatabase.Refresh();                 //刷新

            string copyFullPath = copyPath.Substring(copyPath.IndexOf("Assets\\"));
            //获取新复制的动画状态机
            AnimatorController animationClip = (AnimatorController)AssetDatabase.LoadAssetAtPath(copyFullPath, typeof(AnimatorController));

            DirectoryInfo direction = new DirectoryInfo(animClipPath);
            FileInfo[] files = direction.GetFiles("*.anim", SearchOption.AllDirectories);  //获取动画片段
            AllState.Clear();                                                              //清空本地缓存
            for (int i = 0; i < files.Length; i++)
            {
                Debug.Log("Name:" + files[i].Name);
                FileInfo file = files[i];
                string fileName = file.Name.Substring(0, file.Name.IndexOf("."));
                string fullName = file.FullName.Substring(file.FullName.IndexOf("Assets\\"));
                string[] fileNum = fileName.Split('_');
                string file_Name = fileNum[fileNum.Length - 1];
                AnimationClip clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(fullName, typeof(AnimationClip));
                AllState.Add(file_Name, new ImportAnimConClass                             //按照动画实际作用名称来保存本地
                {
                    fullName = fileName,
                    clip = clip
                });
            }

            for (int i = 0; i < animationClip.layers.Length; i++)                            //获取动画状态机层级
            {
                for (int j = 0; j < animationClip.layers[i].stateMachine.states.Length; j++) //动画状态机层级的片段
                {
                    var state = animationClip.layers[i].stateMachine.states[j].state;
                    //根据动画片段名字来查找
                    string[] strNum = state.name.Split('_');                                 //实际动画名称来查找
                    string state_HalfName = strNum[strNum.Length - 1];
                    if (AllState.ContainsKey(state_HalfName))
                    {
                        state.motion = AllState[state_HalfName].clip;
                        state.name = AllState[state_HalfName].fullName;
                    }
                    else
                    {
                        Debug.LogError(string.Format("未找到相关动画片段:{0}", state.name));
                    }
                }
            }
            Close();
        }
    }
}

public class ImportAnimConClass
{
    public string fullName;
    public AnimationClip clip;
    public ImportAnimConClass()
    {
    }
}

注意事项

1:动画片段名字和动画状态机的名字保持部分一致性;如Characters001_Theme001_Watering 和 Characters002_Theme001_Watering ;
保持Watering一致性;
2:复制的动画状态机和原本的动画状态机路径名字不可保持一致;

包体资源下载

https://download.csdn.net/download/Zjl956321111/20665674

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值