Last active
February 6, 2016 09:26
-
-
Save HaddadBenjamin/5de6acdf4c19a1335838 to your computer and use it in GitHub Desktop.
Behaviour Tree Custom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Classe d'abstraction regroupant les noeuds permettant de parcourir l'arbre, c'est à dire une sequence ou un selector. | |
/// </summary> | |
public abstract class ABehaviourNodeTraversal : ABehaviourNode | |
{ | |
#region Fields | |
private ABehaviourNodeDecorator decorator; | |
#endregion | |
#region Attributes | |
public ABehaviourNodeDecorator Decorator | |
{ | |
get { return decorator; } | |
set { decorator = value; } | |
} | |
#endregion | |
#region Constructor | |
public ABehaviourNodeTraversal() | |
{ | |
this.decorator = new BehaviourNodeDecoratorDefault(); | |
} | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Contient la condition permettant de déterminer si on peut lancer une tâche ou non. | |
/// </summary> | |
public abstract class ABehaviourNodeDecorator | |
{ | |
#region Fields | |
private ABlackboard blackboard; | |
#endregion | |
#region Attributes | |
public ABlackboard Blackboard | |
{ | |
get { return blackboard; } | |
set { blackboard = value; } | |
} | |
#endregion | |
#region Abstract Methods | |
/// <summary> | |
/// Détermine si on peut ou non lancer la tâche. | |
/// </summary> | |
public abstract bool CanPerformTask(); | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Contient une action qui sera lancé si la condition du decorator est bonne. | |
/// </summary> | |
public abstract class ABehaviourNodeTask : ABehaviourNode | |
{ | |
#region Constructor | |
public ABehaviourNodeTask() | |
{ | |
this.Type = EBehaviourNodeType.Task; | |
} | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// On ne peut qu'hériter de cette classe pour pouvoir redéfinir notre classe de donnée. | |
/// </summary> | |
public abstract class ABlackboard | |
{ | |
#region Abstract Methods | |
/// <summary> | |
/// Permet de mettre à jour les valeurs du blackboard. | |
/// </summary> | |
public abstract void Update(); | |
#endregion | |
} | |
/// <summary> | |
/// Classe dont chaque noeud hérite, cette dernière est composé d'un tableau de noeuds et du blackboard. | |
/// </summary> | |
public abstract class ABehaviourNode | |
{ | |
#region Fields | |
private EBehaviourNodeType type; | |
private ABehaviourNode[] nodes; | |
//Les nodes traversal ne devrait en avoir besoin, cependant ceci obligerai de reset tous les blackboard de chaque noeud. | |
private ABlackboard blackboard; | |
#endregion | |
#region Properties | |
protected EBehaviourNodeType Type | |
{ | |
get { return type; } | |
set { type = value; } | |
} | |
public ABehaviourNode[] Nodes | |
{ | |
protected get { return nodes; } | |
set | |
{ | |
nodes = value; | |
Blackboard = blackboard; | |
} | |
} | |
public ABlackboard Blackboard | |
{ | |
protected get { return blackboard; } | |
set | |
{ | |
blackboard = value; | |
if (null != nodes) | |
{ | |
for (byte i = 0; i < nodes.Length; i++) | |
{ | |
nodes[i].Blackboard = blackboard; | |
if (nodes[i].IsOfType(EBehaviourNodeType.Selector) || nodes[i].IsOfType(EBehaviourNodeType.Sequence)) | |
{ | |
ABehaviourNodeTraversal nodeTraversal = nodes[i] as ABehaviourNodeTraversal; | |
if (null != nodeTraversal) | |
{ | |
ABehaviourNodeDecorator nodeDecorator = nodeTraversal.Decorator; | |
if (null != nodeDecorator) | |
nodeDecorator.Blackboard = blackboard; | |
} | |
} | |
} | |
} | |
} | |
} | |
#endregion | |
#region Constructor | |
public ABehaviourNode() | |
{ | |
this.type = EBehaviourNodeType.NotDefine; | |
} | |
#endregion | |
#region Abstract Methods | |
//Execute : pour les taches, PerformTask pour les taches ? | |
public abstract EBehaviourExecuteType Execute(); | |
#endregion | |
#region Behaviour Methods | |
public bool IsOfType(EBehaviourNodeType type) | |
{ | |
return this.type == type; | |
} | |
//Ne devrait pas être ici mais c'est plus pratique. | |
public bool CanRetrieveADecoratorAndPerformHisTask() | |
{ | |
ABehaviourNodeTraversal nodeTraversal = this as ABehaviourNodeTraversal; | |
if (null != nodeTraversal) | |
{ | |
ABehaviourNodeDecorator nodeDecorator = nodeTraversal.Decorator; | |
if (null != nodeDecorator) | |
{ | |
if (nodeDecorator.CanPerformTask()) | |
return true; | |
} | |
} | |
return false; | |
} | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Noeud permettant de parcourir l'arbre de sorte à s'arrêter automatiquement si un des noeuds enfant peut lancer son action. | |
/// </summary> | |
public class BehaviourNodeSelector : ABehaviourNodeTraversal | |
{ | |
#region Constructor | |
public BehaviourNodeSelector() | |
{ | |
this.Type = EBehaviourNodeType.Selector; | |
} | |
#endregion | |
#region Override Methods | |
/// <summary> | |
/// Find the first node where the decorator can perform the task. | |
/// </summary> | |
public override EBehaviourExecuteType Execute() | |
{ | |
EBehaviourExecuteType executeType = EBehaviourExecuteType.Fail; | |
if (null != this.Nodes) | |
{ | |
foreach (ABehaviourNode node in this.Nodes) | |
{ | |
//je récupére le décorateur et si il m'autorise à lancer les sous neouds, je les lance puis je stop l'arbre. | |
if (node.IsOfType(EBehaviourNodeType.Selector) || node.IsOfType(EBehaviourNodeType.Sequence)) | |
{ | |
if (node.CanRetrieveADecoratorAndPerformHisTask()) | |
{ | |
executeType = node.Execute(); | |
if (EBehaviourExecuteType.Success == executeType) | |
break; | |
} | |
} | |
//Autrement Si c'est une tâche je l'execute et stop l'arbre. | |
else if (node.IsOfType(EBehaviourNodeType.Task)) | |
{ | |
executeType = node.Execute(); | |
if (EBehaviourExecuteType.Success == executeType) | |
break; | |
} | |
} | |
} | |
return executeType; | |
} | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Noeud permettant de parcourir l'arbre de sorte à itérer sur tous ses enfants. | |
/// </summary> | |
public class BehaviourNodeSequence : ABehaviourNodeTraversal | |
{ | |
#region Constructor | |
public BehaviourNodeSequence() | |
{ | |
this.Type = EBehaviourNodeType.Sequence; | |
} | |
#endregion | |
#region Override Methods | |
/// <summary> | |
/// Find all node where the decorator can perform the task and perform them. | |
/// </summary> | |
public override EBehaviourExecuteType Execute() | |
{ | |
EBehaviourExecuteType executeType = EBehaviourExecuteType.Fail; | |
if (null != this.Nodes) | |
{ | |
foreach (ABehaviourNode node in this.Nodes) | |
{ | |
//je récupére le décorateur et si il m'autorise à lancer les sous neouds, je les lance puis je stop l'arbre. | |
if (node.IsOfType(EBehaviourNodeType.Selector) || node.IsOfType(EBehaviourNodeType.Sequence)) | |
{ | |
if (node.CanRetrieveADecoratorAndPerformHisTask()) | |
{ | |
EBehaviourExecuteType executeTypeTmp = node.Execute(); | |
if (EBehaviourExecuteType.Success == executeTypeTmp) | |
executeType = executeTypeTmp; | |
} | |
} | |
//Autrement Si c'est une tâche je l'execute et stop l'arbre. | |
else if (node.IsOfType(EBehaviourNodeType.Task)) | |
{ | |
EBehaviourExecuteType executeTypeTmp = node.Execute(); | |
if (EBehaviourExecuteType.Success == executeTypeTmp) | |
executeType = executeTypeTmp; | |
} | |
} | |
} | |
return executeType; | |
} | |
#endregion | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Contient un behaviournode root permettant de lancer une action de façon récursive. | |
/// </summary> | |
public class BehaviourTree | |
{ | |
#region Fields | |
private ABehaviourNode root; | |
private ABlackboard blackboard; | |
#endregion | |
#region Constructor | |
public BehaviourTree(ABehaviourNode root, ABlackboard blackboard) | |
{ | |
this.root = root; | |
this.blackboard = blackboard; | |
this.root.Blackboard = blackboard; | |
} | |
#endregion | |
#region Behaviour | |
public void Execute() | |
{ | |
if (null != this.root) | |
this.root.Execute(); | |
if (null != this.blackboard) | |
this.blackboard.Update(); | |
} | |
#endregion | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public enum EBehaviourExecuteType | |
{ | |
Success, | |
Fail, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public enum EBehaviourNodeType | |
{ | |
NotDefine, | |
Selector, | |
Sequence, | |
Task, | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Root | |
// SelectorA | |
//// / \ | |
// SequenceA task | |
// / \ | |
// SelectorB SelectorC | |
// Decorator Decorator | |
// | | | |
// task task | |
#region Tests classes | |
public class BehaviourTreeTest : MonoBehaviour | |
{ | |
private BehaviourTree behaviourTree; | |
void Start() | |
{ | |
#region Creation de tous les différents noeuds et du blackboard | |
TaskPrintSelectorA taskSelectorA = new TaskPrintSelectorA(); | |
TaskPrintSelectorB taskSelectorB = new TaskPrintSelectorB(); | |
TaskPrintSelectorC taskSelectorC = new TaskPrintSelectorC(); | |
BehaviourNodeSelector selectorA = new BehaviourNodeSelector(); | |
BehaviourNodeSelector selectorB = new BehaviourNodeSelector(); | |
BehaviourNodeSelector selectorC = new BehaviourNodeSelector(); | |
BehaviourNodeSequence sequenceA = new BehaviourNodeSequence(); | |
DecoratorSelectorB decoratorSelectorB = new DecoratorSelectorB(); | |
DecoratorSelectorC decoratorSelectorC = new DecoratorSelectorC(); | |
CustomBlackboard blackboard = new CustomBlackboard(); | |
#endregion | |
#region Liaison des noeuds avec les autres | |
selectorA.Nodes = new ABehaviourNode[] | |
{ | |
sequenceA, | |
taskSelectorA, | |
}; | |
sequenceA.Nodes = new ABehaviourNode[] | |
{ | |
selectorB, | |
selectorC, | |
}; | |
selectorB.Nodes = new ABehaviourNode[] | |
{ | |
taskSelectorB | |
}; | |
selectorC.Nodes = new ABehaviourNode[] | |
{ | |
taskSelectorC | |
}; | |
#endregion | |
#region Liaison des decorators avec les noeuds | |
selectorB.Decorator = decoratorSelectorB; | |
selectorC.Decorator = decoratorSelectorC; | |
#endregion | |
behaviourTree = new BehaviourTree(selectorA, blackboard); | |
} | |
void Update() | |
{ | |
behaviourTree.Execute(); | |
Debug.Log("END"); | |
} | |
} | |
#region Tasks | |
public class TaskPrintSelectorA : ABehaviourNodeTask | |
{ | |
public override EBehaviourExecuteType Execute() | |
{ | |
Debug.Log("Selector A"); | |
return EBehaviourExecuteType.Success; | |
} | |
} | |
public class TaskPrintSelectorB : ABehaviourNodeTask | |
{ | |
public override EBehaviourExecuteType Execute() | |
{ | |
Debug.Log("Selector B"); | |
return EBehaviourExecuteType.Success; | |
} | |
} | |
public class TaskPrintSelectorC : ABehaviourNodeTask | |
{ | |
public override EBehaviourExecuteType Execute() | |
{ | |
Debug.Log("Selector C"); | |
return EBehaviourExecuteType.Success; | |
} | |
} | |
#endregion | |
#region Decorator | |
public class DecoratorSelectorB : ABehaviourNodeDecorator | |
{ | |
public override bool CanPerformTask() | |
{ | |
return false; | |
} | |
} | |
public class DecoratorSelectorC : ABehaviourNodeDecorator | |
{ | |
public override bool CanPerformTask() | |
{ | |
return true; | |
} | |
} | |
#endregion | |
public class CustomBlackboard : ABlackboard | |
{ | |
/// <summary> | |
/// On devra mettre à jour ici notre classe de data pour quelle soit cohérente avec le temps qui passe et notre gameplay. | |
/// </summary> | |
public override void Update() | |
{ | |
} | |
} | |
#endregion | |
//voir si on peut récupérer le blackboard dans un decorateur snas que ça segfualt. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment