前几天接到一个任务,做一个导入、控制模型动画的工具类,没有太具体的要求,于是就自行思考实际需求,最终根据宣雨松老师的一篇博客,自己规范了一下写了一个工具类。相关工具代码及测试用例已上传至Github。

https://github.com/hcy12321/UnityAnimatorControllerMaker

该demo需在导入Unity后执行菜单Tools/CreateAnimator项后再执行。

1.需求及规范

需求是指实际使用时需要实现的地方,规范是最终使用这套工具需要遵守的规则。

1.1 实际需求

1. 能自动遍历fbx文件,且生成对应的AnimatorController文件。

2. 能获取fbx文件中所有的动画片段(AnimationClip),并存入第一步生成的AnimatorController的状态机中。

3.(个人假设需求)状态机默认指向一个空的动画。

1.2 使用规范

1. 所有fbx文件需放置在Assets/Resources/fbx目录(该目录可在代码中更改)中的子目录中,该子目录以fbx名称(不可包含中文)命名,将fbx文件和贴图放到该子目录中,然后将fbx文件重命名为原名_model。

如:wukong.fbx。因和其贴图一起放置在 Assets\Resources\fbx\wukong目录中,然后改名为wukong_model.fbx。

2.功能实现

该部分主要介绍逻辑功能代码

2.1 生成菜单方法

在Editor目录下添加类文件AnimatorTool.cs,该类共有三个方法:

void CreateAnimationAssets(): 工具菜单方法,内有遍历目录生成动画控制器、生成预设的逻辑

using System;
using UnityEngine;
using System.Collections;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.Animations; public class AnimatorTool : MonoBehaviour
{ /// <summary>
/// 菜单方法,遍历文件夹创建Animation Controller
/// </summary>
[MenuItem("Tools/CreateAnimator")]
static void CreateAnimationAssets()
{
string rootFolder = "Assets/Resources/fbx/";
if (!Directory.Exists(rootFolder))
{
Directory.CreateDirectory(rootFolder);
return;
}
// 遍历目录,查找生成controller文件
var folders = Directory.GetDirectories(rootFolder);
foreach (var folder in folders)
{
DirectoryInfo info = new DirectoryInfo(folder);
string folderName = info.Name;
// 创建animationController文件
AnimatorController aController =
AnimatorController.CreateAnimatorControllerAtPath(string.Format("{0}/animation.controller", folder));
// 得到其layer
var layer = aController.layers[];
// 绑定动画文件
AddStateTranstion(string.Format("{0}/{1}_model.fbx", folder, folderName), layer);
// 创建预设
GameObject go = LoadFbx(folderName);
PrefabUtility.CreatePrefab(string.Format("{0}/{1}.prefab", folder, folderName), go);
DestroyImmediate(go);
} } /// <summary>
/// 添加动画状态机状态
/// </summary>
/// <param name="path"></param>
/// <param name="layer"></param>
private static void AddStateTranstion(string path, AnimatorControllerLayer layer)
{
AnimatorStateMachine sm = layer.stateMachine;
// 根据动画文件读取它的AnimationClip对象
var datas = AssetDatabase.LoadAllAssetsAtPath(path);
if (datas.Length == )
{
Debug.Log(string.Format("Can't find clip in {0}", path));
return;
}
// 先添加一个默认的空状态
var emptyState = sm.AddState("empty");
sm.AddAnyStateTransition(emptyState);
// 遍历模型中包含的动画片段,将其加入状态机中
foreach (var data in datas)
{
if (!(data is AnimationClip))
continue;
var newClip = data as AnimationClip;
if (newClip.name.StartsWith("__"))
continue;
// 取出动画名字,添加到state里面
var state = sm.AddState(newClip.name);
state.motion = newClip;
// 把State添加在Layer里面
sm.AddAnyStateTransition(state);
} } /// <summary>
/// 生成带动画控制器的对象
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static GameObject LoadFbx(string name)
{
var obj = Instantiate(Resources.Load(string.Format("fbx/{0}/{0}_model", name))) as GameObject;
obj.GetComponent<Animator>().runtimeAnimatorController =
Resources.Load<RuntimeAnimatorController>(string.Format("fbx/{0}/animation", name));
return obj;
}
}

2.2 测试用例

测试用例中主要包含如何调用播放动画、暂停动画、重播动画等功能。

using UnityEngine;
using System.Collections; public class AnimatorTest : MonoBehaviour
{
private Animator animator; public string animationName = "run"; public float Speed = 1.0f;
// Use this for initialization
void Start()
{
animator = GetComponent<Animator>();
} /// <summary>
/// 添加一些测试功能按钮
/// </summary>
void OnGUI()
{
#if UNITY_EDITOR
if (GUILayout.Button("Play"))
{
Play(animationName);
}
if (GUILayout.Button("Replay"))
{
RePlay(animationName);
}
if (GUILayout.Button("Pause"))
{
Pause();
}
#endif
} /// <summary>
/// 设置速度
/// </summary>
/// <param name="speed"></param>
public void SetSpeed(float speed)
{
Speed = speed;
} /// <summary>
/// 重新播放指定名称动画
/// </summary>
/// <param name="name"></param>
public void RePlay(string name)
{
animator.speed = Speed;
animator.Play(name, , 0.0f);
} /// <summary>
/// 播放指定名称动画
/// </summary>
/// <param name="name"></param>
public void Play(string name)
{
animator.speed = Speed;
animator.Play(name);
} /// <summary>
/// 暂停动画
/// </summary>
public void Pause()
{
animator.speed = 0.0f;
}
}

3.总结

该工具在项目实际使用中还有许多待优化的地方,如只考虑了一个模型,如果是一个人物有多个模型那么还要根据需求再重新设计。还有状态机中还没有根据模型直接生成结构动画、序列动画的功能,需要在以后继续改进。

本工具参考了宣雨松老师的一篇博客:http://www.xuanyusong.com/archives/2811

如有问题请指正,谢谢!

Unity3D读取模型文件自动生成AnimatorController简单实例的更多相关文章

  1. Unity自动生成AnimatorController

    上一篇写了如何自动切割动画,这一篇写如何自动生成AnimatorController. 之前网上查了很多资料,看的一直很蒙,看不懂是怎么回事的,这里我先给大家明确几个概念: 画的不好,大家将就着看,写 ...

  2. 文件参数化-utp框架之根据yaml文件自动生成python文件+utp运行用例

    根据yaml文件自动生成python文件 utp框架: bin目录:存放执行文件(run.py) cases目录:存放生成的用例的python文件(该目录下的文件为根据data目录下的测试用例生成的p ...

  3. Linux设备文件自动生成

    第一种是使用mknod手工创建:# mknod <devfilename> <devtype> <major> <minor> 第二种是自动创建设备节点 ...

  4. 使用maven根据JSON文件自动生成Java POJO类(Java Bean)源文件

    根据JSON文件自动生成Java POJO类(Java Bean)源文件 本文介绍使用程序jsonschema2pojo来自动生成Java的POJO类源文件,本文主要使用maven,其他构建工具请参考 ...

  5. CCS 6新建文件自动生成注释

    对于CCS6,可以通过配置,达到新建源文件或者头文件时,自动生成适当的注释: 一.新建源文件自动生成配置. 在某个文件夹下右击选择 New - Source File. 点击 Configure,再选 ...

  6. IntelliJ IDEA 创建的文件自动生成 Author 注释 签名

    IntelliJ IDEA 创建的文件自动生成 Author 注释 签名1.打开 File --> Setting2.找到 Editor --> File and Code Templat ...

  7. python从入门到大神---4、python3文件操作最最最最简单实例

    python从入门到大神---4.python3文件操作最最最最简单实例 一.总结 一句话总结: python文件操作真的很简单,直接在代码中调用文件操作的函数比如open().read(),无需引包 ...

  8. 读取xml文件中的配置参数实例_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 paras.xml文件 <?xml version="1.0" encoding=" ...

  9. Unity3D研究院之Machine动画脚本自动生成AnimatorController(七十一)

    以前的项目一直不敢用Machine动画,因为当时立项的时候Machine动画还不成熟,最近项目做得差不多了我能有点时间学习,我就想在研究学习学习Machine.用Machine动画的时候需要创建一个A ...

随机推荐

  1. Android 5.0 Default SMS App以及运营商授权SMS App

    已同步更新至个人blog:http://dxjia.cn/2015/08/android-5-default-sms-app/ 题外话:博友们有没有好用的写博客客户端推荐啊,cnblogs推荐的win ...

  2. Django 源码小剖: Django ORM 查询管理器

    ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...

  3. 菜鸟学JS(五)——window.onload与$(document).ready()

    我们继续说JS,我们常常在页面加载完成以后做一些操作,比如一些元素的显示与隐藏.一些动画效果.我们通常有两种方法来完成这个事情,一个就是window.onload事件,另一个就是JQuery的read ...

  4. jQuery Mobile 移动开发中的日期插件Mobiscroll使用说明

    近期在移动方面的开发,使用jQuery Mobile ,移动方面的插件不如Web 方面的插件多,选择的更少,有一些需要自己去封装,但功力尚不足啊. 日期插件JQM也提供了内置的,但样式方面不好看,只好 ...

  5. 【jquery】基于 jquery 实现 ie 浏览器兼容 placeholder 效果

    placeholder 是 html5 新增加的属性,主要提供一种提示(hint),用于描述输入域所期待的值.该提示会在输入字段为空时显示,并会在字段获得焦点时消失.placeholder 属性适用于 ...

  6. LTE工作过程

    LTE工作过程 一.LTE开机及工作过程如下图所示: 二.小区搜索及同步过程 整个小区搜索及同步过程的示意图及流程图如下: 1)   UE开机,在可能存在LTE小区的几个中心频点上接收信号(PSS), ...

  7. chrome https添加信任

    在浏览器地址栏输入:chrome://net-internals/#hsts 然后到Add domain下,Domain添上诸如google.com和google.com.hk ,并勾选Include ...

  8. linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件

    原创,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4555328.html  之前写过一篇<windows下Android利用ant自动编译.修改配置文件.批量 ...

  9. 关于"The dependency was added by the project system and cannot be removed" Error

    阅读一个简单地工程代码,其中一个工程BaseCode是 static lib,另一个工程RunBaseCode使用该lib,但在工程设置的“Linker\Input\AdditionalDepende ...

  10. 转载 ACM训练计划

    leetcode代码 利用堆栈:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/http://oj.leetcode. ...