脚本自动化生成状态机

脚本自动化生成状态机

给角色调试动作,经常会用到状态机,那么一般来说如果就几个角色,那么用Unity的可视化状态机编辑就挺方便了,但是如果有几十个甚至上百个角色的模型,要生成状态机,一个一个调试,不知道要花费多少时间精力,幸好Unity提供了Editor的状态机API,供我们来处理批量的状态机。

首先得有一个模版的AnimatorController

用于处理大部分相同的状态,包括状态机以及状态之间的切换等等

然后拷贝一份到你的角色目录

        if (!File.Exists(animatorControllerPath + fileName))
        {
            FileUtil.CopyFileOrDirectory(templetControlPath + fileName, animatorControllerPath + "/" + generateName);
            Debug.Log("copy animator control success");
        }
        //注意刷新,否则导致animatorController为null
        AssetDatabase.Refresh();

注意刷新下,不然生成的为空

获取角色目录下面所有的动画clip

        string[] assets = AssetDatabase.FindAssets("t:GameObject", animPath.Split());
        AnimationClip[] animClip = new AnimationClip[assets.Length];
        //获得目录下所有的AnimationClip对象
        for (int i = 0; i < assets.Length; ++i)
        {
            string path = AssetDatabase.GUIDToAssetPath(assets[i]);
            animClip[i] = AssetDatabase.LoadAssetAtPath(path, typeof(AnimationClip)) as AnimationClip;
       }
       //如果一个fbx中有多个AnimationClip对象咋办呢?
       var aniArray = AssetDatabase.LoadAllAssetsAtPath(path);
       var filterArray = aniArray.Where(t => t.GetType() == typeof(AnimationClip) && !t.name.Contains("Take")).ToArray();
       for (int j = 0; j < filterArray.Length; j++)
       {
          animClip[j] = filterArray[j] as AnimationClip;
      }

多个AnimationClip,我的做法是获取所有的,然后过滤出来就OK了,可能会有更好的方法,如果有请留言哦!!

拿到AnimatorController里面的状态,然后按照你的规则,往状态里面添加Motion,也就是AnimationClip,就可以啦

 for (int i = 0; i < sm.states.Length; ++i)
 {
         for (int j = 0; j < animClip.Length; ++j)
         {
           if (animClip[j].name.ToLower().Contains(sm.states[i].state.name.ToLower()))
           {
              sm.states[i].state.motion = animClip[j];
           }
           if (matchMap.ContainsKey(sm.states[i].state.name))
           {
              if (animClip[j].name.Contains(matchMap[sm.states[i].state.name]))
               sm.states[i].state.motion = animClip[j];
           }
         }
}

可能有的状态是BleedTree

BlendTree runIdleBlendTree = new BlendTree();
runIdleBlendTree.name = "BlendTree";
runIdleBlendTree.AddChild(idle);
runIdleBlendTree.AddChild(run);
runIdleBlendTree.blendParameter = "Speed";
sm.states[i].state.motion = runIdleBlendTree;

需要生成状态,然后再添加AnimationClip

 for (int i = 0; i < actionClipList.Count; i++)
{
     var action = sm.AddState(actionClipList[i].name, new Vector3(600, 300 + 60 * i));
     var tran = dashState.AddTransition(action);
     tran.exitTime = 1;
     tran.duration = 0;
     tran.offset = 0;
     tran.AddCondition(AnimatorConditionMode.Equals, 5 + i, "CMD");
     action.AddTransition(jumpbackState);
}

补充一下 如果修改Project目录下面的资源可以直接调用

  AssetDatabase.RenameAsset(path, newName);

猜你喜欢

转载自blog.csdn.net/nemo_free/article/details/80083252