Unity自动生成AnimatorController
上一篇写了如何自动切割动画,这一篇写如何自动生成AnimatorController。
之前网上查了很多资料,看的一直很蒙,看不懂是怎么回事的,这里我先给大家明确几个概念:
画的不好,大家将就着看,写这个工具我们会涉及到很多类,类名包含上图哪个关键字,这个东西就跟哪个东西有关
只要大家能明确这些概念,看懂代码就不难了,下面上代码:
using UnityEngine;
using UnityEditor;
using System.IO;
using UnityEditor.Animations; public class CreatePrefab : EditorWindow
{
#region -- 变量定义
private static string mOutputPath = "";
private static bool mIsCreateAnimatorController = true; private static AnimationClip mStart;
private static AnimationClip mTake;
private static AnimationClip mEnd;
#endregion #region -- 系统函数
private void OnGUI()
{
GUILayout.BeginVertical(); //绘制标题
GUILayout.Space();
GUI.skin.label.fontSize = ;
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("Create Prefabs"); //绘制文本
GUILayout.Space();
mOutputPath = EditorGUILayout.TextField("Output Path:", mOutputPath); GUILayout.Space();
mIsCreateAnimatorController = EditorGUILayout.Toggle("Create AnimaControl:", mIsCreateAnimatorController); if (GUILayout.Button("Create"))
{
CreatePrefabs();
} GUILayout.EndVertical();
}
#endregion #region -- 自定义函数
public static void CreateWindow()
{
//绘制窗口
EditorWindow.GetWindow(typeof(CreatePrefab), true, "Create Prefabs");
}
private static void CreatePrefabs()
{
Object[] _objs = Selection.GetFiltered(typeof(GameObject), SelectionMode.Unfiltered);
if (_objs.Length == )
{
Debug.Log("你没有选择任何物体!");
return;
}
for (int i = ; i < _objs.Length; i++)
{
if (!Directory.Exists(Application.dataPath + "/" + mOutputPath))
{
Directory.CreateDirectory(Application.dataPath + "/" + mOutputPath);
}
GameObject _temObJ = _objs[i] as GameObject;
string _outputPath = "";
if (mOutputPath == "")
{
_outputPath = "Assets/";
}
else
{
_outputPath = "Assets/" + mOutputPath + "/";
}
GameObject _prefab = PrefabUtility.CreatePrefab(_outputPath + _temObJ.name + ".prefab", _temObJ);
if (mIsCreateAnimatorController)
{
AnimatorController _animatorController = CreateAnimatorController(AssetDatabase.GetAssetPath(_objs[i]), _temObJ.name + ".controller", _outputPath + "AnimatorControllers");
Animator _animator = _prefab.GetComponent<Animator>();
if (_animator != null)
{
_animator.runtimeAnimatorController = _animatorController;
}
}
}
AssetDatabase.Refresh();
}
private static AnimatorController CreateAnimatorController(string _assetsPath, string _controllerName, string _outPutPath)
{
//创建AnimatorController文件,保存在_outPutPath路径下
if (!Directory.Exists(_outPutPath))
{
Directory.CreateDirectory(_outPutPath);
} //生成动画控制器(AnimatorController)
AnimatorController _animatorController = AnimatorController.CreateAnimatorControllerAtPath(_outPutPath + "/" + _controllerName); //添加参数(parameters)
_animatorController.AddParameter("Normal", AnimatorControllerParameterType.Float);
_animatorController.AddParameter("Play", AnimatorControllerParameterType.Bool); //得到它的Layer, 默认layer为base,可以拓展
AnimatorControllerLayer _layer = _animatorController.layers[]; //把动画文件保存在我们创建的AnimatorController中
AddStateTransition(_assetsPath, _layer);
return _animatorController;
}
private static void AddStateTransition(string _assetsPath, AnimatorControllerLayer _layer)
{
//添加动画状态机(这里只是通过层得到根状态机,并未添加)
AnimatorStateMachine _stateMachine = _layer.stateMachine; // 根据动画文件读取它的AnimationClip对象
var _datas = AssetDatabase.LoadAllAssetsAtPath(_assetsPath);
if (_datas.Length == )
{
Debug.Log(string.Format("Can't find clip in {0}", _assetsPath));
return;
} // 遍历读取模型中包含的动画片段
foreach (var _data in _datas)
{
if (!(_data is AnimationClip))
{
continue;
}
AnimationClip _newClip = _data as AnimationClip;
switch (_newClip.name)
{
case "Start":
mStart = _newClip;
break;
case "End":
mEnd = _newClip;
break;
case "Take":
mTake = _newClip;
break;
}
} // 先添加一个默认的空状态
AnimatorState _emptyState = _stateMachine.AddState("Empty", new Vector3(_stateMachine.entryPosition.x + , _stateMachine.entryPosition.y, )); // 添加与动画名称对应的装态(AnimatorState)到状态机中(AnimatorStateMachine)中,并设置状态
AnimatorState _startState = _stateMachine.AddState(mStart.name, new Vector3(_stateMachine.entryPosition.x + , _stateMachine.entryPosition.y + , ));
_startState.motion = mStart; AnimatorState _endState = _stateMachine.AddState(mEnd.name, new Vector3(_stateMachine.entryPosition.x + , _stateMachine.entryPosition.y - , ));
_endState.motion = mEnd; AnimatorState _take01State = _stateMachine.AddState("Take01", new Vector3(_stateMachine.entryPosition.x + , _stateMachine.entryPosition.y + , ));
_take01State.motion = mTake; AnimatorState _take02State = _stateMachine.AddState("Take02", new Vector3(_stateMachine.entryPosition.x + , _stateMachine.entryPosition.y - , ));
_take02State.motion = mTake;
_take02State.speed = -; //连接每个状态,并添加切换条件
AnimatorStateTransition _animatorStateTransition = _emptyState.AddTransition(_startState);
_animatorStateTransition.AddCondition(AnimatorConditionMode.Greater, , "Normal");
_animatorStateTransition.hasExitTime = false;
_animatorStateTransition.duration = ; _animatorStateTransition = _emptyState.AddTransition(_endState);
_animatorStateTransition.AddCondition(AnimatorConditionMode.Less, , "Normal");
_animatorStateTransition.hasExitTime = false;
_animatorStateTransition.duration = ; _animatorStateTransition = _startState.AddTransition(_take01State);
_animatorStateTransition.AddCondition(AnimatorConditionMode.If, , "Play");
_animatorStateTransition.hasExitTime = false;
_animatorStateTransition.duration = ; _animatorStateTransition = _endState.AddTransition(_take02State);
_animatorStateTransition.AddCondition(AnimatorConditionMode.If, , "Play");
_animatorStateTransition.hasExitTime = false;
_animatorStateTransition.duration = ;
}
#endregion }
代码很详细了,也写了很多注释,这里就不多说了,大家自己看。
有个坑和大家说一下,我们是有 bool 类型的参数,如何设置 bool 类型的参数呢?
我开始天真的以为是这样的:
_animatorStateTransition.AddCondition(AnimatorConditionMode.If, 0, "BoolParameter");
_animatorStateTransition.AddCondition(AnimatorConditionMode.If, 1, "BoolParameter");
不知道有多少同学和我一样,有这种天真的想法,然后你会发现这样设置根本没用,值全部都为True,根本设置不了false
后来查了好久资料,才发现是这样设置 bool 类型的参数的:
_animatorStateTransition.AddCondition(AnimatorConditionMode.If, 0, "BoolParameter"); 为True
_animatorStateTransition.AddCondition(AnimatorConditionMode.IfNot, 0, "BoolParameter");为False
实在是坑,不想说话。。。。。。。
附上一张效果图
填写好输出路径,在 Project 视图中选中模型,点击 Create 按钮吧,然后你会发现预制体以及动画状态机都帮你制作好了,嘿嘿!
然后状态之间具体怎么连,这部分是需要自己根据项目需求自己写的,我这里只是给大家一个例子。
Unity自动生成AnimatorController的更多相关文章
- Unity 自动生成组件索引类工具
Unity 自动生成组件索引类工具 需求由来 我们在写UI类时 需要获取预设中的组件 joystick = transform.Find("joystick"); backgrou ...
- Unity3D研究院之Machine动画脚本自动生成AnimatorController(七十一)
以前的项目一直不敢用Machine动画,因为当时立项的时候Machine动画还不成熟,最近项目做得差不多了我能有点时间学习,我就想在研究学习学习Machine.用Machine动画的时候需要创建一个A ...
- Unity3D研究院之Machine动画脚本自动生成AnimatorController
原地址: http://www.xuanyusong.com/archives/2811 以前的项目一直不敢用Machine动画,因为当时立项的时候Machine动画还不成熟,最近项目做得差不多了我能 ...
- Unity3D读取模型文件自动生成AnimatorController简单实例
前几天接到一个任务,做一个导入.控制模型动画的工具类,没有太具体的要求,于是就自行思考实际需求,最终根据宣雨松老师的一篇博客,自己规范了一下写了一个工具类.相关工具代码及测试用例已上传至Github. ...
- unity组件路径自动生成
unity 有时候找路径太麻烦 写了一个自动生成脚本的工具 using System.Collections.Generic; using System.IO; using System.Text; ...
- Unity 导出的android项目自动生成Private Libraries
如果Unity里面Plugins/Android 添加了 jar 文件,则导出Android 项目时会自动生成 Private Libraries. 而且里面的项还删不掉 然后在网上搜了一下,找到了原 ...
- Unity2D研究院之自动生成动画、AnimationController、Prefab(一)
http://www.xuanyusong.com/archives/3243 国庆了,回家了.时刻还是要吃一颗学习的心,在家了也要抽出时间好好学习一下.之前MOMO一直没研究过Unity2D,今天研 ...
- 9.1.3 .net framework通过业务逻辑层自动生成WebApi的做法
首先需要说明的是这是.net framework的一个组件,而不是针对.net core的.目前工作比较忙,因此.net core的转换正在编写过程中,有了实现会第一时间贴出来. 接下来进入正题.对于 ...
- 自动生成查找组件的lua代码
本篇主要解决的问题是使用lua脚本编写unity业务逻辑时,自动生成一些查找组件及绑定控件事件的lua代码! 现在很多unity项目都是用ulua作为热更新解决方案,因此需要用lua来写相关的逻辑,经 ...
随机推荐
- runners
saltstack return 除了在配置文件中可以定义外(太繁琐),还可以自定义retunner,当然,这需要通过代码实现了,实现方式和自定义的pillar和grains类似,步骤如下: #创建_ ...
- 项目需求分析与建议-NABCD模型
N(Need 需求) 首先我们的创意解决了现有阶段学校查空余教师的问题,充分解决了同学们上自习却找不到教室的苦衷,同时也会适当的拓展一些适当的学习计时功能或者每日一语等等,来帮助同学们来控制好学习时间 ...
- Django Cache缓存系统学习--数据库缓存
Django是动态网站,用户每一次请求页面,服务器都会执行以下操作:数据库查询.渲染模版.执行业务逻辑,最后生成用户可查看的页面.当访问量比较大的时候,会消耗掉大量的资源,这时候就会考虑到缓存问题. ...
- OGRE中Any 类型的实现
[OGRE中Any类型的实现] OGRE中实现了一个class Any,使用Any 可以在上下文中传递任意类型的数据.其本质实现原理就是通过指针. Any 只包含一个成员变量,类型为 placehol ...
- python 的xlwt模块
一.安装 ♦ python官网下载https://pypi.python.org/pypi/xlwt模块安装. ♦或者在cmd窗口 pip install xlrd 二.使用 1.导入模块 imp ...
- H5(ionic2+VScode) 环境安装
一:node.js.npm.cnpm.cordova环境安装 介绍下概念 node.js 非阻塞异步的Ajax 操作基础框架. npm 国外的node.js 包管理器 cnpm 国内淘宝的node.j ...
- Exp4 恶意代码分析 20165110
Exp4 恶意代码分析 20165110 一.实践目标 1.是监控你自己系统的运行状态,看有没有可疑的程序在运行. 2.是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生 ...
- python3安装pcap遇到的问题
最近想在win7上安装pypcap,遇到了一下问题,现在大概总结一下: 直接使用pip install pypcap,提示pcap.h not found: 网上下载pypcap安装包,运行pytho ...
- zigbee_蓝牙_wifi的比较与区别分析
现在无线通读热了起来.三个最大的Wifi.ZigBee.蓝牙它们三个始终困惑着我.那么它们三个有什么区别呢? Zigbee 和蓝牙都是一项无线通信技术.ZigBee的传输距离视发射功率而定,有几百到几 ...
- 网络通信实验(1)STM32F4 以太网简介
STM32F4 以太网简介 STM32F407 芯片自带以太网模块,该模块包括带专用 DMA 控制器的 MAC 802.3(介质访问控制)控制器,支持介质独立接口 (MII) 和简化介质独立接口 (R ...