unity5之程式碼建立狀態機,玩的666
http://blog.csdn.net/litaog00/article/details/50483189
最近做專案的時候用到了狀態機,網上搜了一下帖子,大部分都是簡單介紹使用方法的,講解的詳細的很少。作者
好好研究了一番,感覺很有必要和大家分享一下。技術和靈感,來源於網路,共享於網路~
好多個human模型有好多個動作片段,這些片段又分出若干大類和若干小類,一個主角可能會應用到所有的這些片
段,當滿足一定條件時從一類動作中隨機取出一個播放,進遊戲的時候有的動作條件滿足有的不滿足隨著玩的進度
又可能會滿足#@#@#%@!!&*&,,,,略複雜,總之就是有好多動作(200個左右),有的能播,有的不能播
,作者(頭硬)一心想用一個狀態機來解決所有問題,所以就用程式碼建立吧,畢竟這麼多動作,讓策劃去擺,費時
費力還容易出錯,特別在設定transition的條件時,呵呵,那就程式碼建立吧,既能體現情懷又能提高自己。
首先網上搜了搜,只有雨鬆momo的一篇http://www.xuanyusong.com/archives/2811(冒犯引用一下),介紹了大
概思想和用法,但是比較舊,要知道作者用的可是unity3d5.2.2版的,不同及需要注意的地方依次列出:
1.AnimatorController所在的庫由UnityEditorInternal變為UnityEditor.Animations
2.AnimatorController裡可以建立layer,每個layer有個statemachine(我們通常叫‘某個角色的狀態機’好
像不合適,應該叫‘某個角色的AnimatorController’)
- //建立controller
- AnimatorController controller=AnimatorController.CreateAnimatorControllerAtPath("Assets/Resources/CharacterAnim/Play2Controllor_2.controller");
-
AnimatorControllerLayer layer=controller.layers[0];
- AnimatorStateMachine machine=layer.stateMachine;
3.建立引數,
- controller.AddParameter("zhan->pa",AnimatorControllerParameterType.Trigger);
引數型別有4種:int、float、bool、trigger(作者之前用4.2版的時候還沒有trigger,只有int、float
、bool、vector)
有了引數,就有判斷條件了,判斷條件的型別有
- AnimatorConditionMode.If;
- AnimatorConditionMode.IfNot;
- AnimatorConditionMode.Equals;
- AnimatorConditionMode.NotEqual;
- AnimatorConditionMode.Greater;
- AnimatorConditionMode.Less;
4.新增內容
新增oneState
- oneState=machine.AddState(名字,位置)
- AnimatorStateTransition defaultTransition=machine.AddAnyStateTransition(oneState);
- AnimatorStateMachine sub2Machine=machine.AddStateMachine(名字,位置)
- AnimatorStateTransition transition1=machine.AddAnyStateTransition(oneState);
- AnimatorStateTransition transition2=sub2Machine.AddAnyStateTransition(twoState);
transition1和transition2不是從同一個anyState出發的,而是從各自狀態機的anyState出發的(子狀態
機也有個anyState,但是在controller編輯器裡看不出來)
5.雨鬆momo的帖子裡有網友問到:如果fbx裡有多個clip,用AssetDatabase.LoadAssetAtPath(xxx.fbx)
如何取到呢?那麼答案來了
- Object[] objects=AssetDatabase.LoadAllAssetsAtPath("Assets/Art/Animation/"+fbxName);
- for(int m=0;m<objects.Length;m++)
- {
- <span style="white-space:pre"> </span>if(objects[m].GetType()==typeof(AnimationClip) && !objects[m].name.Contains("Take 001"))
- {
- AnimationClip clip=(AnimationClip)objects[m];
- if(clip.name.Equals("chushidongzuo001"))
- {
- defaultState.motion=clip;
- }
- else
- {
- addAnimationClip(clip,actionDetails,machine,haveSub3);
- }
- }
- }
注意到了嗎?AssetDatabase.LoadAllAssetsAtPath可以把fbx裡的所有資訊取到,clip、骨骼節點、mesh。。。,
然後過濾一下下。而AssetDatabase.LoadAssetAtPath<AnimationClip>("xxx.FBX")只能取到此fbx下第一個clip。
好了,就寫到這裡,下面把整個程式碼貼出來,供大家參考~
- using UnityEngine;
- using System.Collections.Generic;
- using UnityEditor;
- //using UnityEditorInternal;
- using UnityEditor.Animations;
- using System.IO;
- publicclass Play2ControllerGenerator : EditorWindow {
- publicenum ActionType:int
- {
- undefine=0,
- zhan,
- tang,
- cewo,
- pa,
- guodu,
- kaichang,
- jieshu,
- wu
- }
- publicenum ActionStyle:int
- {
- normal=0,
- qingchun,
- keai,
- gaoleng,
- yundong,
- chengshu,
- xinggan
- }
- privatestaticstring[] sub2MachineNames=newstring[]{"undefine","zhan","tang","cewo","pa","guodu","kaichang","jieshu","wu"};
- privatestaticstring[] sub3MachineNames=newstring[]{"normal","qingchun","keai","gaoleng","yundong","chengshu","xinggan"};
- privateconststring ParamNameTransitionAction="transitionAction";
- privateconststring ParamNameActionId="actionId";
- privateconstfloat TransitionDuring=0.4f;
- //
- [MenuItem("LoveLive/核心玩法2/生成狀態機")]
- privatestaticvoid addWindow()
- {
- Rect rect=new Rect(0,0,600,300);
- Play2ControllerGenerator window=EditorWindow.GetWindowWithRect<Play2ControllerGenerator>(rect,true,"生成核心玩法狀態機(省得策劃自己擺了)");
- window.minSize=new Vector2(300,100);
- window.maxSize=new Vector2(600,300);
- window.Show();
- }
- void OnGUI()
- {
- EditorGUILayout.BeginVertical();
- EditorGUILayout.LabelField("需要\"Assets/Resources/Config/action.txt\"");
- EditorGUILayout.LabelField("需要\"Assets/Art/Animation\"下的動作檔案");
- EditorGUILayout.EndVertical();
- EditorGUILayout.Separator();
- EditorGUILayout.LabelField("生成的狀態機在這個位置:\"Assets/Resources/CharacterAnim/Play2Controllor_2.controller\"