Unity自动创建AnimatorController

这个是我现在所知最正确的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;}}// 创建prefabstring 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

相关文章:

你感兴趣的文章:

标签云: