Unity3D拓展编辑器之自动生成AnimatorContr
很惭愧从事游戏开发三年半才开始记录,之前也有一些零散信息记录在有道云笔记里,但都不成体系。那就从现在开始吧!
最近项目刚出完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下。
usingUnityEditor;usingUnityEngine;usingSystem.Collections;usingSystem.IO;publicclassEditorAnimatorController{//controller模板名和拷贝后的名称privatestaticstringfileName="AnimatorController.controller";[MenuItem("AnimatorController/CreateAnimatorController")]staticvoidCreateAnimatorController(){//获得当前选中为GameObject格式的文件object[]objs=Selection.GetFiltered(typeof(GameObject),SelectionMode.Assets);GameObjectselectObj=null;if(objs.Length<1){Debug.LogError("Pleaseselectamodelfile");return;}//判断是否选中了skin文件,名字含有"@skin"foreach(GameObjectobjinobjs){if(obj.name.Contains("@skin")){selectObj=obj;}}//如果没有选中,则提示错误并返回if(selectObj==null){Debug.LogError("Pleaseselectaskinfile");return;}//获得模板文件的路径(没有找到获得上一级上上级目录的API,只好使用字符切割了)stringselectObjPath=AssetDatabase.GetAssetPath((Object)selectObj);string[]array=selectObjPath.Split('/');stringtempletControlPath=null;stringanimatorControllerPath=null;for(inti=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("Thetempletcontrolfileismissing");return;}//如果还没有生成AnimatorController文件,则将模板文件拷贝if(!File.Exists(animatorControllerPath+fileName)){FileUtil.CopyFileOrDirectory(templetControlPath+fileName,animatorControllerPath+fileName);Debug.Log("copyanimatorcontrolsuccess");}//注意下方高能坑!之前没有刷新,导致下面的animatorController一直为nullAssetDatabase.Refresh();//通过AssetDatabase类load新拷贝的文件,获得animatorController对象UnityEditor.Animations.AnimatorControlleranimatorController=AssetDatabase.LoadAssetAtPath(animatorControllerPath+fileName,typeof(UnityEditor.Animations.AnimatorController))asUnityEditor.Animations.AnimatorController;//获得layer信息UnityEditor.Animations.AnimatorControllerLayerlayer=animatorController.layers[0];//获得stateMachine信息UnityEditor.Animations.AnimatorStateMachinesm=layer.stateMachine;//获得该人物文件夹下Anim文件夹中的动作资源stringanimPath=animatorControllerPath+"Anim";string[]assets=AssetDatabase.FindAssets("t:GameObject",animPath.Split());AnimationClip[]animClip=newAnimationClip[assets.Length];//获得目录下所有的AnimationClip对象for(inti=0;i<assets.Length;++i){stringpath=AssetDatabase.GUIDToAssetPath(assets[i]);animClip[i]=AssetDatabase.LoadAssetAtPath(path,typeof(AnimationClip))asAnimationClip;}//通过名称匹配,将AnimationClip一一对应上state的motionfor(inti=0;i<sm.states.Length;++i){for(intj=0;j<animClip.Length;++j){if(animClip[j].name.Contains(sm.states[i].state.name)){sm.states[i].state.motion=animClip[j];}}}}}
好啦,先记录到这~周一继续写将当前AnimatorController附加到人物身上并生成Prefab到指定目录~
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。