-
Notifications
You must be signed in to change notification settings - Fork 195
/
NPBehaveExampleEnemyAI.cs
87 lines (72 loc) · 3.16 KB
/
NPBehaveExampleEnemyAI.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
using UnityEngine;
using NPBehave;
public class NPBehaveExampleEnemyAI : MonoBehaviour
{
private Blackboard blackboard;
private Root behaviorTree;
void Start()
{
// create our behaviour tree and get it's blackboard
behaviorTree = CreateBehaviourTree();
blackboard = behaviorTree.Blackboard;
// attach the debugger component if executed in editor (helps to debug in the inspector)
#if UNITY_EDITOR
Debugger debugger = (Debugger)this.gameObject.AddComponent(typeof(Debugger));
debugger.BehaviorTree = behaviorTree;
#endif
// start the behaviour tree
behaviorTree.Start();
}
private Root CreateBehaviourTree()
{
// we always need a root node
return new Root(
// kick up our service to update the "playerDistance" and "playerLocalPos" Blackboard values every 125 milliseconds
new Service(0.125f, UpdatePlayerDistance,
new Selector(
// check the 'playerDistance' blackboard value.
// When the condition changes, we want to immediately jump in or out of this path, thus we use IMMEDIATE_RESTART
new BlackboardCondition("playerDistance", Operator.IS_SMALLER, 7.5f, Stops.IMMEDIATE_RESTART,
// the player is in our range of 7.5f
new Sequence(
// set color to 'red'
new Action(() => SetColor(Color.red)) { Label = "Change to Red" },
// go towards player until playerDistance is greater than 7.5 ( in that case, _shouldCancel will get true )
new Action((bool _shouldCancel) =>
{
if (!_shouldCancel)
{
MoveTowards(blackboard.Get<Vector3>("playerLocalPos"));
return Action.Result.PROGRESS;
}
else
{
return Action.Result.FAILED;
}
}) { Label = "Follow" }
)
),
// park until playerDistance does change
new Sequence(
new Action(() => SetColor(Color.grey)) { Label = "Change to Gray" },
new WaitUntilStopped()
)
)
)
);
}
private void UpdatePlayerDistance()
{
Vector3 playerLocalPos = this.transform.InverseTransformPoint(GameObject.FindGameObjectWithTag("Player").transform.position);
behaviorTree.Blackboard["playerLocalPos"] = playerLocalPos;
behaviorTree.Blackboard["playerDistance"] = playerLocalPos.magnitude;
}
private void MoveTowards(Vector3 localPosition)
{
transform.localPosition += localPosition * 0.5f * Time.deltaTime;
}
private void SetColor(Color color)
{
GetComponent<MeshRenderer>().material.SetColor("_Color", color);
}
}