first commit
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using System.Linq;
|
||||
|
||||
namespace NodeCanvas.BehaviourTrees
|
||||
{
|
||||
|
||||
public static class BehaviourTreeExtensions
|
||||
{
|
||||
|
||||
///<summary>Replace the node with another</summary>
|
||||
public static Node ReplaceWith(this Node node, System.Type t) {
|
||||
|
||||
var newNode = node.graph.AddNode(t, node.position);
|
||||
foreach ( var c in node.inConnections.ToArray() ) {
|
||||
c.SetTargetNode(newNode);
|
||||
}
|
||||
|
||||
foreach ( var c in node.outConnections.ToArray() ) {
|
||||
c.SetSourceNode(newNode);
|
||||
}
|
||||
|
||||
if ( node.graph.primeNode == node ) {
|
||||
node.graph.primeNode = newNode;
|
||||
}
|
||||
|
||||
if ( node is ITaskAssignable && newNode is ITaskAssignable ) {
|
||||
var assignableNode = node as ITaskAssignable;
|
||||
var assignableNewNode = newNode as ITaskAssignable;
|
||||
try { assignableNewNode.task = assignableNode.task; }
|
||||
catch { /* cant assign */ }
|
||||
}
|
||||
|
||||
node.graph.RemoveNode(node);
|
||||
return newNode;
|
||||
}
|
||||
|
||||
///<summary>Create a new SubTree out of the branch of the provided root node</summary>
|
||||
public static BehaviourTree ConvertToSubTree(this BTNode root) {
|
||||
|
||||
if ( !UnityEditor.EditorUtility.DisplayDialog("Convert to SubTree", "This will create a new SubTree out of this branch.\nAre you sure?", "Yes", "No!") ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var newBT = EditorUtils.CreateAsset<BehaviourTree>();
|
||||
if ( newBT == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var subTreeNode = root.graph.AddNode<SubTree>(root.position);
|
||||
subTreeNode.subGraph = newBT;
|
||||
|
||||
for ( var i = 0; i < root.inConnections.Count; i++ ) {
|
||||
root.inConnections[i].SetTargetNode(subTreeNode);
|
||||
}
|
||||
|
||||
root.inConnections.Clear();
|
||||
|
||||
newBT.primeNode = DuplicateBranch(root, newBT);
|
||||
DeleteBranch(root);
|
||||
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
return newBT;
|
||||
}
|
||||
|
||||
///<summary>Delete the whole branch of provided root node along with the root node</summary>
|
||||
public static void DeleteBranch(this BTNode root) {
|
||||
var graph = root.graph;
|
||||
foreach ( var node in root.GetAllChildNodesRecursively(true).ToArray() ) {
|
||||
graph.RemoveNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
///<summary>Duplicate a node along with all children hierarchy</summary>
|
||||
public static Node DuplicateBranch(this BTNode root, Graph targetGraph) {
|
||||
|
||||
if ( targetGraph == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var newNode = root.Duplicate(targetGraph);
|
||||
var dupConnections = new List<Connection>();
|
||||
for ( var i = 0; i < root.outConnections.Count; i++ ) {
|
||||
dupConnections.Add(root.outConnections[i].Duplicate(newNode, DuplicateBranch((BTNode)root.outConnections[i].targetNode, targetGraph)));
|
||||
}
|
||||
newNode.outConnections.Clear();
|
||||
foreach ( var c in dupConnections ) {
|
||||
newNode.outConnections.Add(c);
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
|
||||
///<summary>Decorates BT node with decorator type</summary>
|
||||
public static Node DecorateWith(this BTNode node, System.Type t) {
|
||||
var newNode = node.graph.AddNode(t, node.position + new UnityEngine.Vector2(0, -80));
|
||||
if ( node.inConnections.Count == 0 ) {
|
||||
node.graph.ConnectNodes(newNode, node);
|
||||
} else {
|
||||
var parent = node.inConnections[0].sourceNode;
|
||||
var parentConnection = node.inConnections[0];
|
||||
var index = parent.outConnections.IndexOf(parentConnection);
|
||||
node.graph.RemoveConnection(parentConnection);
|
||||
node.graph.ConnectNodes(newNode, node);
|
||||
node.graph.ConnectNodes(parent, newNode, index);
|
||||
NodeCanvas.Editor.GraphEditorUtility.activeElement = newNode;
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
|
||||
///<summary>Fetch all child nodes of the node recursively, optionaly including this. In other words, this fetches the whole branch.</summary>
|
||||
public static List<BTNode> GetAllChildNodesRecursively(this BTNode root, bool includeThis) {
|
||||
|
||||
var childList = new List<BTNode>();
|
||||
if ( includeThis ) {
|
||||
childList.Add(root);
|
||||
}
|
||||
|
||||
foreach ( BTNode child in root.outConnections.Select(c => c.targetNode) ) {
|
||||
childList.AddRange(child.GetAllChildNodesRecursively(true));
|
||||
}
|
||||
|
||||
return childList;
|
||||
}
|
||||
|
||||
///<summary>Fetch all child nodes of this node with their depth in regards to this node. So, first level children will have a depth of 1 while second level a depth of 2</summary>
|
||||
public static Dictionary<BTNode, int> GetAllChildNodesWithDepthRecursively(this BTNode root, bool includeThis, int startIndex) {
|
||||
|
||||
var childList = new Dictionary<BTNode, int>();
|
||||
if ( includeThis ) {
|
||||
childList[root] = startIndex;
|
||||
}
|
||||
|
||||
foreach ( BTNode child in root.outConnections.Select(c => c.targetNode) ) {
|
||||
foreach ( var pair in child.GetAllChildNodesWithDepthRecursively(true, startIndex + 1) ) {
|
||||
childList[pair.Key] = pair.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return childList;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user