Unity3D行爲樹插件Behave學習筆記

Behave1.4行爲樹插件

下載地址:http://pan.baidu.com/s/1i4uuX0Ldom

安裝插件和使用

咱們先來看看插件的安裝和基本使用方法,新建一個Unity3D項目,這裏我使用的是5.0以上的版本:ui

導入插件

第一步固然是導入下載好的插件包了,操做略過...spa

建立資源

首先咱們建立一個名爲BT的文件夾,點擊Project面板的create來建立相應的資源:插件

咱們會在Asset目錄下生成一個NewBehaveLibrary0.asset的文件,咱們重命名爲MyBehaveLibrary後將其拖入新建的BT文件夾中便可。debug

編輯資源

咱們選中建立的資源,在Inspector中能夠看到以下的界面:調試

咱們點擊Edit library後會彈出兩個窗口,須要注意的是有一個窗口被另外一個徹底覆蓋了,拖拽一下就能夠看到了。點擊behave browse面板的create建立一個collection,再點擊一次create建立一個tree咱們就有了一個行爲樹了。code

接下來咱們選中新建立的NewTree1在behave editor面板就能夠編輯這個行爲樹了。orm

咱們將面板下方的Action拖拽到面板中並在Inspector修改該節點的名稱爲MyAction:blog

接下來咱們在頂部中間的方塊拉出一條線,連線到咱們的MyAction頂上,這樣就把這個節點添加到該行爲樹上了。遊戲

好了到目前爲止,咱們的編輯就算是完成了。

編譯資源

到目前爲止,咱們的資源還不能在項目中直接使用,咱們須要先對其進行編譯,選中咱們的library,在Inspector中會出現選項:

咱們點擊一下Build library debug就能夠編譯出在項目中可使用的資源了,以下:

編輯代碼

編輯完成後,接下來咱們該怎麼使用行爲樹呢?看官們請接着看。

首先咱們建立一個類Demo1Agent:

 1 using Behave.Runtime;
 2 using UnityEngine;
 3 using System.Collections;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo1Agent : IAgent {
 7 
 8     public void Reset (Tree sender) {
 9 
10     }
11     
12     public int SelectTopPriority (Tree sender, params int[] IDs) {
13         return 0;
14     }
15     
16     public BehaveResult Tick (Tree sender, bool init) {
17         Debug.Log("調用系統的Tick方法");
18         return BehaveResult.Success;
19     }
20 
21     public BehaveResult TickMyActionAction(Tree sender) {
22         Debug.Log("個人action");
23         return BehaveResult.Success;
24     }
25 }

咱們建立了一個實現了IAgent的類,這個類會和一個行爲樹進行綁定,這裏須要注意的是Tick和TickMyActionAction方法,在一個行爲樹中,同一時刻只有一個節點會執行,而咱們的「MyAction」執行時,會尋找TickMyActionAction方法進行調用,這裏的方法命名有一個規則:「Tick」+節點名稱+「Action」,若是行爲樹找到了對應當前節點名稱的方法就會進行調用,不然會調用Tick方法。

接下來咱們建立一個類Demo1:

 1 using UnityEngine;
 2 using System.Collections;
 3 using Behave.Runtime;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo1 : MonoBehaviour {
 7 
 8     Tree m_Tree;
 9     Demo1Agent agent;
10 
11     void Start () {
12         agent = new Demo1Agent ();
13         m_Tree = BLMyBehaveLibrary.InstantiateTree(BLMyBehaveLibrary.TreeType.NewCollection1_NewTree1, agent);
14     }
15 
16     void Update () {
17         m_Tree.Tick();
18     }
19 }

這個類就比較簡單了,咱們經過BLMyBehaveLibrary建立一個和Demo1Agent的實例綁定的行爲樹,其中BLMyBehaveLibrary和NewCollection1_NewTree1都是咱們以前編輯好編譯生成的行爲樹代碼,每幀調用行爲樹的Tick方法便可。

調試行爲樹

咱們在場景中添加一個GameObject並綁定Demo1便可,運行就能夠看到「個人Action」的輸出了。

節點詳解

目前behave提供了下面6個節點,咱們來具體的看看:

Action

動做節點,執行核心邏輯的節點,該節點咱們以前已經使用過了,主要用來實現咱們須要的邏輯功能。

這裏主要說一下Tick方法的3個返回值:

1 namespace Behave.Runtime
2 {
3     public enum BehaveResult
4     {
5         Running,
6         Success,
7         Failure
8     }
9 }
  • Running表示當前節點須要繼續運行,下一次Tick時仍然會執行該節點。
  • Success表示節點執行完畢,並且執行成功。
  • Failure表示節點執行完畢,並且執行失敗。

Decorator

裝飾節點只會有一個子節點,做用爲經過判斷來控制是否執行其子節點,咱們來看看裝飾節點的使用方法:

首先咱們建立一個新的行爲樹,並添加一個裝飾節點和一個動做節點:

咱們新建一個Demo2Agent:

 1 using Behave.Runtime;
 2 using UnityEngine;
 3 using System.Collections;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo2Agent : IAgent {
 7 
 8     private bool _shoulDo;
 9 
10     public void Reset (Tree sender) {
11         
12     }
13     
14     public int SelectTopPriority (Tree sender, params int[] IDs) {
15         return 0;
16     }
17     
18     public BehaveResult Tick (Tree sender, bool init) {
19         Debug.Log("調用系統的Tick方法");
20         return BehaveResult.Success;
21     }
22 
23     public BehaveResult TickMyDecoratorDecorator(Tree sender) {
24         _shoulDo = !_shoulDo;
25         if (_shoulDo) {
26             Debug.Log("執行子節點");
27             return BehaveResult.Success;
28         } else {
29             Debug.Log("不執行子節點");
30             return BehaveResult.Failure;
31         }
32     }
33 
34     public BehaveResult TickMyActionAction(Tree sender) {
35         Debug.Log("個人action");
36         return BehaveResult.Success;
37     }
38 }

這裏要注意的是,裝飾節點的命名爲:「Tick」+節點名稱+「Decorator」,不是Action了。

接下來編譯咱們的行爲樹,添加一個類Demo2:

 1 using UnityEngine;
 2 using System.Collections;
 3 using Behave.Runtime;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo2 : MonoBehaviour {
 7 
 8     Tree m_Tree;
 9     Demo2Agent agent;
10     
11     void Start () {
12         agent = new Demo2Agent ();
13         m_Tree = BLMyBehaveLibrary.InstantiateTree(BLMyBehaveLibrary.TreeType.NewCollection1_NewTree2, agent);
14     }
15     
16     void Update () {
17         m_Tree.Tick();
18     }
19 }

添加到場景就能夠查看效果了。

Sequence

順序節點會讓鏈接它的子節點從左到右依次執行,  每一個節點從底部的線決定了順序,擺放的位置可有可無,若是第一個子節點返回失敗,則整個節點返回失敗。若是該子節點返回成功,則會自動往右邊一個子節點執行,若是該節點返回runing,則會從新開始運行。

咱們建立一個新的行爲樹,以下:

咱們新建一個Demo3Agent:

 1 using Behave.Runtime;
 2 using UnityEngine;
 3 using System.Collections;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo3Agent : IAgent {
 7 
 8     public GameObject cube;
 9     public float time;
10 
11     float nowTime = 0;
12 
13     public void Reset (Tree sender) {
14         
15     }
16     
17     public int SelectTopPriority (Tree sender, params int[] IDs) {
18         return 0;
19     }
20     
21     public BehaveResult Tick (Tree sender, bool init) {
22         Debug.Log("調用系統的Tick方法");
23         return BehaveResult.Success;
24     }
25 
26     public BehaveResult TickMyAction1Action(Tree sender) {
27         Debug.Log("個人action1");
28         if (cube.transform.position.x >= 3.0f) {
29             cube.transform.position = new Vector3(3.0f, 0, 0);
30             return BehaveResult.Success;
31         }
32         cube.transform.Translate(new Vector3(2.0f * time, 0, 0));
33         return BehaveResult.Running;
34     }
35 
36     public BehaveResult TickMyAction2Action(Tree sender) {
37         Debug.Log("個人action2");
38         if (nowTime >= 1.0f) {
39             nowTime = 0;
40             cube.transform.localEulerAngles = new Vector3(0, 0, 0);
41             return BehaveResult.Success;
42         }
43         cube.transform.Rotate(new Vector3(360.0f * time, 0, 0));
44         nowTime += time;
45         return BehaveResult.Running;
46     }
47 
48     public BehaveResult TickMyAction3Action(Tree sender) {
49         Debug.Log("個人action3");
50         if (cube.transform.position.x <= 0) {
51             cube.transform.position = new Vector3(0, 0, 0);
52             return BehaveResult.Success;
53         }
54         cube.transform.Translate(new Vector3(-2.0f * time, 0, 0));
55         return BehaveResult.Running;
56     }
57 }

咱們再建立一個Demo3:

 1 using UnityEngine;
 2 using System.Collections;
 3 using Behave.Runtime;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo3 : MonoBehaviour {
 7 
 8     public GameObject cube;
 9 
10     Tree m_Tree;
11     Demo3Agent agent;
12     
13     void Start () {
14         agent = new Demo3Agent ();
15         agent.cube = cube;
16         m_Tree = BLMyBehaveLibrary.InstantiateTree(BLMyBehaveLibrary.TreeType.NewCollection1_NewTree3, agent);
17     }
18     
19     void Update () {
20         agent.time = Time.deltaTime;
21         m_Tree.Tick();
22     }
23 }

咱們在場景裏添加一個Cube,把Demo3拖入並綁定Cube就能夠查看效果了;

這裏的效果是Cube先向前移動,而後旋轉一下再向後移動,如此反覆。

Selector

選擇節點子節點會從左到右依次執行,和順序節點不一樣的是,選擇節點的子節點返回成功,則整個節點返回成功,若是子節點返回失敗,則運行右邊的一個子節點,並繼續運行,一直到運行到子節點的末尾一個,則返回失敗,下一次選擇節點再被觸發的時候,又從最左邊 第一個節點開始運行。

咱們建立一個新的行爲樹,以下:

咱們新建一個Demo4Agent:

 1 using Behave.Runtime;
 2 using UnityEngine;
 3 using System.Collections;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo4Agent : IAgent {
 7 
 8     public GameObject cube;
 9     public float time;
10     
11     float nowTime = 0;
12 
13     public void Reset (Tree sender) {
14         
15     }
16     
17     public int SelectTopPriority (Tree sender, params int[] IDs) {
18         return 0;
19     }
20     
21     public BehaveResult Tick (Tree sender, bool init) {
22         Debug.Log("調用系統的Tick方法");
23         return BehaveResult.Success;
24     }
25 
26     public BehaveResult TickMyAction1Action(Tree sender) {
27         Debug.Log("個人action1");
28         if (nowTime >= 1.0f) {
29             nowTime = 0;
30             cube.transform.position = new Vector3(0, 0, 0);
31             //失敗則執行下一個節點
32             if (Random.value > 0.5f) {
33                 return BehaveResult.Failure;
34             }
35             return BehaveResult.Success;
36         }
37         cube.transform.Translate(new Vector3(2.0f * time, 0, 0));
38         nowTime += time;
39         return BehaveResult.Running;
40     }
41     
42     public BehaveResult TickMyAction2Action(Tree sender) {
43         Debug.Log("個人action2");
44         if (nowTime >= 1.0f) {
45             nowTime = 0;
46             cube.transform.localEulerAngles = new Vector3(0, 0, 0);
47             //失敗則執行下一個節點
48             if (Random.value > 0.5f) {
49                 return BehaveResult.Failure;
50             }
51             return BehaveResult.Success;
52         }
53         cube.transform.Rotate(new Vector3(360.0f * time, 0, 0));
54         nowTime += time;
55         return BehaveResult.Running;
56     }
57     
58     public BehaveResult TickMyAction3Action(Tree sender) {
59         Debug.Log("個人action3");
60         if (nowTime >= 1.0f) {
61             nowTime = 0;
62             cube.transform.localScale = new Vector3(1, 1, 1);
63             //失敗則執行下一個節點
64             if (Random.value > 0.5f) {
65                 return BehaveResult.Failure;
66             }
67             return BehaveResult.Success;
68         }
69         cube.transform.localScale = new Vector3(nowTime, nowTime, nowTime);
70         nowTime += time;
71         return BehaveResult.Running;
72     }
73 }

咱們再建立一個Demo4:

 1 using UnityEngine;
 2 using System.Collections;
 3 using Behave.Runtime;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo4 : MonoBehaviour {
 7 
 8     public GameObject cube;
 9     
10     Tree m_Tree;
11     Demo4Agent agent;
12     
13     void Start () {
14         agent = new Demo4Agent ();
15         agent.cube = cube;
16         m_Tree = BLMyBehaveLibrary.InstantiateTree(BLMyBehaveLibrary.TreeType.NewCollection1_NewTree4, agent);
17     }
18     
19     void Update () {
20         agent.time = Time.deltaTime;
21         m_Tree.Tick();
22     }
23 }

咱們的小正方形會先運行Action1,而後有50%的機會進入Action2,進入Action2後又有50%的機會進入Action3。

Parallel

並行節點會從左到右觸發它全部的子節點工做,對於並行節點有兩個重要的設置,一個是子節點完成,一個是組件完成,子節點完成參數決定了子節點的返回值該如何處理:

  1. 若是並行節點設置爲成功或者失敗,那麼不管它返回的是成功仍是失敗,子節點的輸出都標記爲完成。
  2. 若是並行節點設置爲成功,那麼子節點的輸出只在返回成功時候才標記爲完成。在觸發全部的子節點工做後,一個子節點返回失敗就會讓整個並行組件返回失敗。
  3. 並行節點設置爲失敗的話也會同理,子節點只有在返回完成時,它纔會返回失敗。

咱們建立一個新的行爲樹,以下:

選擇並行節點能夠看到屬性:

這裏的意思是:全部的子節點都返回成功則退出該節點。

咱們新建一個Demo5Agent:

 1 using Behave.Runtime;
 2 using UnityEngine;
 3 using System.Collections;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo5Agent : IAgent {
 7 
 8     public GameObject cube;
 9     public float time;
10     
11     float nowTime = 0;
12 
13     public void Reset (Tree sender) {
14         
15     }
16     
17     public int SelectTopPriority (Tree sender, params int[] IDs) {
18         return 0;
19     }
20     
21     public BehaveResult Tick (Tree sender, bool init) {
22         Debug.Log("調用系統的Tick方法");
23         return BehaveResult.Success;
24     }
25 
26     public BehaveResult TickMyAction1Action(Tree sender) {
27         Debug.Log("個人action1");
28         if (cube.transform.position.x >= 3.0f) {
29             cube.transform.position = new Vector3(3.0f, 0, 0);
30             return BehaveResult.Success;
31         }
32         cube.transform.Translate(new Vector3(2.0f * time, 0, 0));
33         return BehaveResult.Running;
34     }
35     
36     public BehaveResult TickMyAction2Action(Tree sender) {
37         Debug.Log("個人action2");
38         if (nowTime >= 1.0f) {
39             nowTime = 0;
40             cube.transform.localEulerAngles = new Vector3(0, 0, 0);
41             return BehaveResult.Success;
42         }
43         cube.transform.Rotate(new Vector3(360.0f * time, 0, 0));
44         nowTime += time;
45         return BehaveResult.Running;
46     }
47     
48     public BehaveResult TickMyAction3Action(Tree sender) {
49         Debug.Log("個人action3");
50         if (cube.transform.position.x <= 0) {
51             cube.transform.position = new Vector3(0, 0, 0);
52             return BehaveResult.Success;
53         }
54         cube.transform.Translate(new Vector3(-2.0f * time, 0, 0));
55         return BehaveResult.Running;
56     }
57 }

咱們再建立一個Demo5:

 1 using UnityEngine;
 2 using System.Collections;
 3 using Behave.Runtime;
 4 using Tree = Behave.Runtime.Tree;
 5 
 6 public class Demo5 : MonoBehaviour {
 7 
 8     public GameObject cube;
 9     
10     Tree m_Tree;
11     Demo5Agent agent;
12     
13     void Start () {
14         agent = new Demo5Agent ();
15         agent.cube = cube;
16         m_Tree = BLMyBehaveLibrary.InstantiateTree(BLMyBehaveLibrary.TreeType.NewCollection1_NewTree5, agent);
17     }
18     
19     void Update () {
20         agent.time = Time.deltaTime;
21         m_Tree.Tick();
22     }
23 }

運行遊戲:會看見小正方形會旋轉着前進,由於並行是全部子節點每幀都會被調用到,當兩個子節點都返回成功時退出該節點。小正方形恢復到原點。

工程下載

http://pan.baidu.com/s/1sjZNg9B

相關文章
相關標籤/搜索