温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Unity3D拓展编辑器之自动生成AnimatorContr

发布时间:2020-07-15 09:43:26 来源:网络 阅读:3178 作者:hongjunyu128 栏目:游戏开发

很惭愧从事游戏开发三年半才开始记录,之前也有一些零散信息记录在有道云笔记里,但都不成体系。那就从现在开始吧!


最近项目刚出完demo,有些衔接的时间,花了一天时间写了一个方便美术同学操作的小工具。第一次写拓展编辑器,做好之后超级兴奋的说,哈哈~这个工具主要是根据某类人物的AnimatorController的模板,拷贝并将当前人物的动作自动赋值的过程,避免了手动拖拽动作操作的繁杂和失误。比如,monster一般可以共用AnimatorController的layer信息,只是各个state中的motion要对应各个人物的动作。


当然,写的还不够灵活,有一些目录和命名的要求。

1、AnimatorController模板文件的目录地址:放在该类型人物的文件夹下,如monster文件夹下

2、每个人物模型的skin文件的目录地址:放在该人物的文件夹下,如怪物1文件夹下

3、各个动作文件命名规范:怪物名@动作名,如monster_blk@skin、monster_blk@idlel01


monster文件夹

    —AnimatorController(monster共用的AnimatorController模板文件

    —monster_blk(怪物1的资源文件夹)

        —Anim(怪物1的动作文件夹)

        —Materials(怪物1的材质文件夹)

        —Tex(怪物1的贴图文件夹)

        —monster_blk@skin(怪物1的skin文件)

    —monster_blkw(怪物2的资源文件夹)

        —Anim(怪物2的动作文件夹)

        —Materials(怪物2的材质文件夹)

        —Tex(怪物2的贴图文件夹)

        —monster_blkw@skin(怪物2的skin文件)


和美术同学规范好细节后,就可以开始编码啦~话不多说,直接上代码~

新建一个EditorAnimatorController脚本,放在工程目录Editor下。


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

public class EditorAnimatorController{
        //controller模板名和拷贝后的名称
	private static string fileName = "AnimatorController.controller";

	[MenuItem("AnimatorController/CreateAnimatorController")]
	static void CreateAnimatorController()
	{
	        //获得当前选中为GameObject格式的文件
		object[] objs = Selection.GetFiltered (typeof(GameObject), SelectionMode.Assets);
		GameObject selectObj = null;

		if (objs.Length < 1) 
		{
			Debug.LogError("Please select a model file");
			return;
		}

		//判断是否选中了skin文件,名字含有"@skin"
		foreach (GameObject obj in objs) 
		{
			if(obj.name.Contains("@skin"))
			{
				selectObj = obj;
			}
		}
                //如果没有选中,则提示错误并返回
		if (selectObj == null) 
		{
			Debug.LogError("Please select a skin file");
			return;
		}

		//获得模板文件的路径(没有找到获得上一级上上级目录的API,只好使用字符切割了)
		string selectObjPath = AssetDatabase.GetAssetPath((Object) selectObj);
		string[] array = selectObjPath.Split('/');
		string templetControlPath = null;
		string animatorControllerPath = null;
		for (int i = 0; i < array.Length; ++i) 
		{
			if(i == (array.Length - 1) )
				continue;

			animatorControllerPath +=  array[i] + "/";

			if(i == (array.Length - 2) )
				continue;

			templetControlPath += array[i] + "/";
		}

		//判断模板文件是否在该类型人物文件夹下
		if (!File.Exists (templetControlPath + fileName))
		{
			Debug.LogError("The templet control file is missing");
			return;
		}
                //如果还没有生成AnimatorController文件,则将模板文件拷贝
		if (!File.Exists (animatorControllerPath + fileName))
		{
			FileUtil.CopyFileOrDirectory (templetControlPath + fileName, animatorControllerPath + fileName);
			Debug.Log("copy animator control success");
		}
		//注意下方高能坑!之前没有刷新,导致下面的animatorController一直为null
		AssetDatabase.Refresh ();

		//通过AssetDatabase类load新拷贝的文件,获得animatorController对象
		UnityEditor.Animations.AnimatorController animatorController = AssetDatabase.LoadAssetAtPath (animatorControllerPath + fileName, typeof(UnityEditor.Animations.AnimatorController)) as UnityEditor.Animations.AnimatorController;
		//获得layer信息
		UnityEditor.Animations.AnimatorControllerLayer layer = animatorController.layers[0];
		//获得stateMachine信息
		UnityEditor.Animations.AnimatorStateMachine sm = layer.stateMachine;

		//获得该人物文件夹下Anim文件夹中的动作资源 
		string animPath = animatorControllerPath + "Anim";
		string[] assets = AssetDatabase.FindAssets( "t:GameObject" , animPath.Split() );
		AnimationClip[] animClip = new AnimationClip[assets.Length];
		//获得目录下所有的AnimationClip对象
		for (int i = 0; i < assets.Length; ++i)
		{
			string path = AssetDatabase.GUIDToAssetPath(assets[i]);
			animClip[i] = AssetDatabase.LoadAssetAtPath(path, typeof(AnimationClip)) as AnimationClip;
		}
		//通过名称匹配,将AnimationClip一一对应上state的motion
		for (int i = 0; i < sm.states.Length; ++i) 
		{
			for(int j = 0 ; j < animClip.Length ; ++j)
			{
				if(animClip[j].name.Contains(sm.states[i].state.name)) 
				{
					sm.states[i].state.motion = animClip[j];
				}
			}
		}
	}
}


好啦,先记录到这~周一继续写将当前AnimatorController附加到人物身上并生成Prefab到指定目录~





向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI