首页 > 编程语言 > 详细

Unity自动创建AnimatorController

时间:2015-02-18 21:01:12      阅读:4410      评论:0      收藏:0      [点我收藏+]

        这个是我现在所知最正确的MecAnim的用法了。先上代码:

using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System;
using System.Collections;
using System.Collections.Generic;

public class GetAnimationClips : AssetPostprocessor
{
    void OnPostprocessModel(GameObject go)
    {
        List<AnimationClip> clips = new List<AnimationClip>();
        UnityEngine.Object[] objects = AssetDatabase.LoadAllAssetsAtPath(assetPath);
        Debug.Log(objects.Length);
        foreach (var obj in objects) {
             AnimationClip clip = obj as AnimationClip;
            if (clip != null && clip.name.IndexOf("__preview__") == -1) {
                clips.Add(clip);
            }
        }

        CreateAnimationController(assetPath, clips);
     }

    static void CreateAnimationController(string path, List<AnimationClip> clips)
    {
        path = path.Replace("\\", "/").Replace(".FBX", ".fbx");
        string acPath = path.Replace(".fbx", ".controller");
        string prefabPath = path.Replace(".fbx", ".prefab");

        // 创建动画控制器
        AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(acPath);
        AnimatorControllerLayer layer = animatorController.GetLayer(0);
        UnityEditorInternal.StateMachine sm = layer.stateMachine;
        Vector3 anyStatePosition = sm.anyStatePosition;
        float OFFSET_X = 220;
        float OFFSET_Y = 60;
        float ITEM_PER_LINE = 4;
        float originX = anyStatePosition.x - OFFSET_X * (ITEM_PER_LINE / 2.5f);
        float originY = anyStatePosition.y + OFFSET_Y;
        float x = originX;
        float y = originY;
        foreach (AnimationClip newClip in clips) {
            State state = sm.AddState(newClip.name.ToLower());
            state.SetAnimationClip(newClip, layer);
            state.position = new Vector3(x, y, 0);
            x += OFFSET_X;
            if (x >= originX + OFFSET_X * ITEM_PER_LINE) {
                x = originX;
                y += OFFSET_Y;
            }
        }

        // 创建prefab
        string name = path.Substring(path.LastIndexOf("/") + 1).Replace(".fbx", "");
        prefabPath = "Assets/Resources/" + name + ".prefab";
        GameObject go = AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) as GameObject;
        go.name = name;
        Animator animator = go.GetComponent<Animator>();
        if (animator == null) {
            animator = go.AddComponent<Animator>();
        }
        animator.applyRootMotion = false;
        animator.runtimeAnimatorController = animatorController;
        //AssetDatabase.CreateAsset(go, prefabPath);
        PrefabUtility.CreatePrefab(prefabPath, go);
        GameObject.DestroyImmediate(go, true);

        AssetDatabase.SaveAssets();
    }
}

        这个代码所做的事情是,在加载模型的时候,自动加载其动画,然后生成AnimatorController文件(控制动画流转的文件),生成对应的prefab(用于直接通过代码实例化)。有几个知识点:

        1、AssetDatabase.LoadAllAssetsAtPath通过这个函数可以加载fbx文件(包含所有动画信息)。这个是根据fbx文件获取AnimationClip的方法。

        2、AssetPostprocessor这个是Unity资源加载的接口。自动生成动画控制器的代码可以不放在这里,可以扩展Menu菜单完成对应功能(如遍历选择文件夹下的fbx文件并进行相关处理)。

        

        这个是我现在所知的MMO中最正确的MecAnim的用法:

        1、不要手工编辑.controller文件,无论是加载动画还是连线,在MMO中动画量相当庞大,人工编辑这些绝对是无法让人接受的。

        2、MecAnim有一定优势,如重定向,现在几乎所有的MMO都是用的老的动画系统。不过我认为,我的这个方法可以兼容老的动画系统和新的动画系统,或者说,可以使老的动画系统的项目平滑过渡到新的动画系统

        3、我们维护动画的方式可能是这样的,美术给出模型,如果可能的话,最好切分好动画(貌似maya是支持的,blender也是支持的,但是3dmax未知,比如我使用blender导出火炬之光的模型到unity中,unity可以直接识别出切分好的动画,而不需要手动切动画)。如果没有的话,就需要一个配置文件(比如excel)维护好动画的起始、结束帧的信息。在导入模型的时候,可以根据这个配置文件通过代码添加AnimationClip。

        4、自动生成AnimatorController的思路一样可以应用到老的动画系统,因为其最核心的内容就是如何通过fbx获取到AnimationClip信息。如果是老的动画系统就是把AnimationClip添加到prefab的Animation的动画列表中。

        5、我是如何使用新的动画系统的:

GameObject prefab = Resources.Load("player") as GameObject;
        GameObject go = Instantiate(prefab) as GameObject;
        Animator animator = go.GetComponent<Animator>();
        animator.CrossFade("idle", 0.25f, 0);

       controller里面不连线,也不用param控制,它只是一个容器。代码中直接使用CrossFade进行动画切换。这个有一个额外的好处,AssetBundle打包的prefab无法在Unity的Animator分页中看到其数据。自己控制动画切换可以做的更加自由。

Unity自动创建AnimatorController

原文:http://blog.csdn.net/langresser_king/article/details/43878113

(0)
(1)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!