Skip to content

Commit 2233e18

Browse files
committed
Start Observer Pattern for Behaviors
1 parent 32b7359 commit 2233e18

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1823
-1773
lines changed

Assets/Scripts.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/AI.meta renamed to Assets/Scripts/AI.meta

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,123 @@
1-
using Assets.Scripts.AI.Components;
2-
using System;
3-
using System.Collections;
4-
using System.Collections.Generic;
5-
using UnityEngine;
6-
using Newtonsoft.Json;
7-
using System.ComponentModel;
8-
9-
namespace Assets.Scripts.AI
10-
{
11-
public class BehaviorManager : MonoBehaviour
12-
{
13-
public string FileName = "";
14-
/// <summary>
15-
/// The file to actually save/load to/from.
16-
/// </summary>
17-
[JsonIgnore]
18-
[Description("The currently loaded tree asset that will be run.")]
19-
public BehaviorTreeManagerAsset BehaviorTreeFile;
20-
21-
/// <summary>
22-
/// Primary Runner for this manager.
23-
/// Runs all sub-behaviors/trees at the same time using the specified parallelrunner attributes.
24-
/// </summary>
25-
private ParallelRunner runner = new ParallelRunner("Main Root", -1, -1);
26-
public ParallelRunner Runner
27-
{
28-
get
29-
{
30-
return runner;
31-
}
32-
33-
set
34-
{
35-
runner = value;
36-
}
37-
}
38-
39-
/// <summary>
40-
/// Seconds between every tick. At "0" this will tick every frame (basically an update loop)
41-
/// </summary>
42-
[SerializeField]
43-
[Description("Seconds between every tick. At 0 this will tick every frame")]
44-
public float SecondsBetweenTicks = 0.1f;
45-
46-
/// <summary>
47-
/// Number of times to tick the full trees. Set to a negative number to make an infinitely running behavior tree.
48-
/// </summary>
49-
[SerializeField]
50-
[Description("Times to tick this tree before stopping. Negative values indicate infinitely running behavior.")]
51-
public int TimesToTick = 10;
52-
53-
[Description("Open a list to splice other trees into this tree.")]
54-
public bool spliceNewIntoTree = false;
55-
/// <summary>
56-
/// A list of trees to splice into the current tree. These trees are not directly editable.
57-
/// </summary>
58-
[JsonIgnore]
59-
public List<BehaviorTreeManagerAsset> SpliceList;
60-
61-
private bool initialized = false;
62-
63-
void OnEnable()
64-
{
65-
InitIfNeeded();
66-
}
67-
68-
public void InitIfNeeded()
69-
{
70-
if (initialized == false)
71-
{
72-
Reinitialize();
73-
}
74-
}
75-
76-
public void Reinitialize()
77-
{
78-
//TODO: Change to runner extension (?)
79-
Runner = BehaviorTreeFile.LoadFromJSON(this);
80-
81-
82-
if(spliceNewIntoTree) SpliceIntoRunner();
83-
initialized = true;
84-
}
85-
86-
//TODO: Add ILogger *(perhaps Observer pattern? This is our "singleton")*
87-
//Dispatch messages to observed classes and receive that information here...
88-
//How to store? List? Dictionary? My face? Cat Pictures?
89-
90-
/// <summary>
91-
/// Ticks on the aggregate ParallelRunner then continues ticking for as long as the runner is in running state
92-
/// </summary>
93-
/// <returns></returns>
94-
IEnumerator Start()
95-
{
96-
WaitForSeconds wfs = new WaitForSeconds(SecondsBetweenTicks);
97-
98-
Debug.Log("Starting ticks on Runner: \n\t" + Runner.ToString());
99-
yield return Runner.Tick();
100-
while (Runner.CurrentState == BehaviorState.Running && (TimesToTick != 0))
101-
{
102-
yield return StartCoroutine(Runner.Tick(wfs));
103-
--TimesToTick;
104-
}
105-
106-
Debug.Log("All Coroutines Should be DONE now! Ending all to make sure....");
107-
StopAllCoroutines();
108-
}
109-
110-
/// <summary>
111-
/// Splice all trees in the "splice" area of the editor and return "true" if new trees were spliced.
112-
/// </summary>
113-
/// <returns></returns>
114-
public bool SpliceIntoRunner()
115-
{
116-
if (SpliceList != null)
117-
{
118-
foreach (var behaviorAsset in SpliceList)
119-
{
120-
if (behaviorAsset == null) return false;
121-
122-
var spliceTree = behaviorAsset.LoadFromJSON();
123-
124-
foreach (var behavior in spliceTree.Children)
125-
{
126-
if (behavior.Depth == -1 || behavior.Name == "root") continue;
127-
128-
dynamic newBehavior = Activator.CreateInstance(Type.GetType(((BehaviorTreeElement)behavior).ElementType),
129-
behavior.Name, behavior.Depth, behavior.ID);
130-
newBehavior.BehaviorTreeManager = this;
131-
Runner.AddChild(newBehavior);
132-
}
133-
}
134-
135-
return true;
136-
}
137-
else return false;
138-
}
139-
}
140-
}
1+
using Assets.Scripts.AI.Components;
2+
using System;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using UnityEngine;
6+
using Newtonsoft.Json;
7+
using System.ComponentModel;
8+
9+
namespace Assets.Scripts.AI
10+
{
11+
public class BehaviorManager : MonoBehaviour, ILo
12+
{
13+
public string FileName = "";
14+
/// <summary>
15+
/// The file to actually save/load to/from.
16+
/// </summary>
17+
[JsonIgnore]
18+
[Description("The currently loaded tree asset that will be run.")]
19+
public BehaviorTreeManagerAsset BehaviorTreeFile;
20+
public ParallelRunner Runner { get; set; } = new ParallelRunner("Main Root", -1, -1);
21+
22+
/// <summary>
23+
/// Seconds between every tick. At "0" this will tick every frame (basically an update loop)
24+
/// </summary>
25+
[SerializeField]
26+
[Description("Seconds between every tick. At 0 this will tick every frame")]
27+
public float SecondsBetweenTicks = 0.1f;
28+
29+
/// <summary>
30+
/// Number of times to tick the full trees. Set to a negative number to make an infinitely running behavior tree.
31+
/// </summary>
32+
[SerializeField]
33+
[Description("Times to tick this tree before stopping. Negative values indicate infinitely running behavior.")]
34+
public int TimesToTick = 10;
35+
36+
[Description("Open a list to splice other trees into this tree.")]
37+
public bool spliceNewIntoTree = false;
38+
/// <summary>
39+
/// A list of trees to splice into the current tree. These trees are not directly editable.
40+
/// </summary>
41+
[JsonIgnore]
42+
public List<BehaviorTreeManagerAsset> SpliceList;
43+
44+
private bool initialized = false;
45+
46+
void OnEnable()
47+
{
48+
InitIfNeeded();
49+
}
50+
51+
public void InitIfNeeded()
52+
{
53+
if (initialized == false)
54+
{
55+
Reinitialize();
56+
}
57+
}
58+
59+
public void Reinitialize()
60+
{
61+
//TODO: Change to runner extension (?)
62+
Runner = BehaviorTreeFile.LoadFromJSON(this);
63+
64+
65+
if(spliceNewIntoTree) SpliceIntoRunner();
66+
initialized = true;
67+
}
68+
69+
//TODO: Add ILogger *(perhaps Observer pattern? This is our "singleton")*
70+
//Dispatch messages to observed classes and receive that information here...
71+
//How to store? List? Dictionary? My face? Cat Pictures?
72+
73+
/// <summary>
74+
/// Ticks on the aggregate ParallelRunner then continues ticking for as long as the runner is in running state
75+
/// </summary>
76+
/// <returns></returns>
77+
IEnumerator Start()
78+
{
79+
WaitForSeconds wfs = new WaitForSeconds(SecondsBetweenTicks);
80+
81+
Debug.Log("Starting ticks on Runner: \n\t" + Runner.ToString());
82+
yield return Runner.Tick();
83+
while (Runner.CurrentState == BehaviorState.Running && (TimesToTick != 0))
84+
{
85+
yield return StartCoroutine(Runner.Tick(wfs));
86+
if(TimesToTick > 0) --TimesToTick;
87+
}
88+
89+
Debug.Log("All Coroutines Should be DONE now! Ending all to make sure....");
90+
StopAllCoroutines();
91+
}
92+
93+
/// <summary>
94+
/// Splice all trees in the "splice" area of the editor and return "true" if new trees were spliced.
95+
/// </summary>
96+
/// <returns></returns>
97+
public bool SpliceIntoRunner()
98+
{
99+
if (SpliceList != null)
100+
{
101+
foreach (var behaviorAsset in SpliceList)
102+
{
103+
if (behaviorAsset == null) return false;
104+
105+
var spliceTree = behaviorAsset.LoadFromJSON();
106+
107+
foreach (var behavior in spliceTree.Children)
108+
{
109+
if (behavior.Depth == -1 || behavior.Name == "root") continue;
110+
111+
dynamic newBehavior = Activator.CreateInstance(Type.GetType(((BehaviorTreeElement)behavior).ElementType),
112+
behavior.Name, behavior.Depth, behavior.ID);
113+
newBehavior.BehaviorTreeManager = this;
114+
Runner.AddChild(newBehavior);
115+
}
116+
}
117+
118+
return true;
119+
}
120+
else return false;
121+
}
122+
}
123+
}
Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
namespace Assets.Scripts.AI
2-
{
3-
//TODO: Error state? Needed? Useful?
4-
/// <summary>
5-
/// Null usually means this behavior has not started or is in an error state.
6-
/// Fail, Success, and Running are for checking the current state from the parent object.
7-
/// </summary>
8-
public enum BehaviorState
9-
{
10-
Null = 0,
11-
Fail,
12-
Success,
13-
Running
14-
}
1+
namespace Assets.Scripts.AI
2+
{
3+
//TODO: Error state? Needed? Useful?
4+
/// <summary>
5+
/// Null usually means this behavior has not started or is in an error state.
6+
/// Fail, Success, and Running are for checking the current state from the parent object.
7+
/// </summary>
8+
public enum BehaviorState
9+
{
10+
Null = 0,
11+
Fail,
12+
Success,
13+
Running
14+
}
1515
}
Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)