@一键自动状态机复用
代码块
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