Files
tianrunCRM/Assets/CoolapeFrame/3rd/Hivemind/Editor/BTEditorManager.cs
2020-07-04 14:41:25 +08:00

293 lines
7.8 KiB
C#

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.IO;
using Coolape;
namespace Hivemind
{
/*
* This manager is created by the BTInspector, the custom inspector for BehaviorTree assets.
* Every time the inspector receives the OnEnable message, a fresh manager is created, and
* destroyed when the inspector receives the OnDisable message.
*
* Its main responsibility is to serve as the sole route for BehaviorTree manipulation.
*
* It achieves that by exposing a selected BehaviorTree (determined by the current BehaviorTree
* being inspected in BTInspector) to the BTEditorWindow
*
* BTEditorWindow manages its own sub systems to provide editing functionality, and forwards
* all actual manipulations to this manager.
*
* Creation of new BehaviorTrees are also handled here.
*/
public class BTEditorManager : ScriptableObject
{
public Editor btInspector;
public Editor nodeInspector;
public BehaviorTreeAgent inspectedAgent;
public BTEditorWindow editorWindow;
public Node selectedNode;
public BehaviorTree _behaviorTree;
public BehaviorTree behaviorTree {
get { return _behaviorTree; }
set {
_behaviorTree = value;
if (_behaviorTree != null) {
_behaviorTree.nodeWillTick = OnNodeWillTick;
_behaviorTree.nodeDidTick = OnNodeDidTick;
}
}
}
public BTAsset btAsset;
public void OnNodeWillTick (Node node)
{
if (inspectedAgent.debugMode) {
Debug.Log (node.GetType ().Name);
}
}
public void OnNodeDidTick (Node node, Status result)
{
if (editorWindow != null)
editorWindow.Repaint ();
}
public static BTEditorManager Manager { get; private set; }
public static BTEditorManager CreateInstance (BehaviorTree bt, BTAsset asset)
{
if (Manager == null) {
Manager = (BTEditorManager)ScriptableObject.CreateInstance (typeof(BTEditorManager));
Manager.behaviorTree = bt;
Manager.btAsset = asset;
}
return Manager;
}
// Lifecycle
public void OnEnable ()
{
hideFlags = HideFlags.HideAndDontSave;
}
public void OnDestroy ()
{
Manager = null;
DestroyImmediate (behaviorTree);
}
// Asset management ------------------------------------------------------------------------------------------------------------------------------------
[MenuItem ("Coolape/New Behavior Tree", false, 3)]
static void CreateNewBehaviorTree (MenuCommand menuCommand)
{
// string path = AssetDatabase.GetAssetPath(Selection.activeObject);
// if (path == "")
// path = "Assets";
// else if (Path.GetExtension(path) != "")
// path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), "");
string basePath = PStr.b ().a ("Assets/").a (CLPathCfg.self.basePath).a ("/xRes/carbonEvent/").e ();
string fullPath = EditorUtility.SaveFilePanel ("Save Carbon Event", basePath, "New Behavior Tree", "asset");
if (string.IsNullOrEmpty (fullPath)) {
return;
}
// fullPath = AssetDatabase.GenerateUniqueAssetPath (fullPath);
fullPath = fullPath.Substring(fullPath.IndexOf("/Assets/") + 1);
BehaviorTree bt = ScriptableObject.CreateInstance<BehaviorTree> ();
Root root = ScriptableObject.CreateInstance<Root> ();
root.editorPosition = new Vector2 (0, 0);
bt.SetRoot (root);
BTAsset btAsset = ScriptableObject.CreateInstance<BTAsset> ();
btAsset.Serialize (bt);
AssetDatabase.CreateAsset (btAsset, fullPath);
AssetDatabase.Refresh ();
EditorUtility.FocusProjectWindow ();
Selection.activeObject = btAsset;
}
public void Dirty ()
{
if (editorWindow != null)
editorWindow.Repaint ();
btAsset.Serialize (behaviorTree);
EditorUtility.SetDirty (btAsset);
}
// Behavior Tree manipulation --------------------------------------------------------------------------------------------------------------------------
public void Add (Node parent, Vector2 position, string nodeType)
{
Node node = null;
switch (nodeType) {
case "Action":
node = behaviorTree.CreateNode<NodeAction> ();
break;
case "Branch":
node = behaviorTree.CreateNode<NodeBranch> ();
break;
case "Together":
node = behaviorTree.CreateNode<NodeTogether> ();
break;
// case "Inverter":
// node = behaviorTree.CreateNode<Inverter>();
// break;
// case "Parallel":
// node = behaviorTree.CreateNode<Parallel>();
// break;
// case "RandomSelector":
// node = behaviorTree.CreateNode<RandomSelector>();
// break;
// case "Repeater":
// node = behaviorTree.CreateNode<Repeater>();
// break;
// case "Selector":
// node = behaviorTree.CreateNode<Selector>();
// break;
// case "Sequence":
// node = behaviorTree.CreateNode<Sequence>();
// break;
// case "Succeeder":
// node = behaviorTree.CreateNode<Succeeder>();
// break;
// case "UntilSucceed":
// node = behaviorTree.CreateNode<UntilSucceed>();
// break;
}
behaviorTree.nodes.Add (node);
if (parent != null && parent.CanConnectChild) {
if (parent.ChildCount > 0) {
Node lastSibling = parent.Children [parent.ChildCount - 1];
node.editorPosition = lastSibling.editorPosition + new Vector2 (GridRenderer.step.x * 10, 0);
} else {
node.editorPosition = new Vector2 (parent.editorPosition.x, parent.editorPosition.y + GridRenderer.step.y * 10);
}
parent.ConnectChild (node);
// SortChildren(parent);
} else {
float xOffset = position.x % GridRenderer.step.x;
float yOffset = position.y % GridRenderer.step.y;
float xoffset1 = editorWindow.view.scrollPoint.x;
float yoffset1 = editorWindow.view.scrollPoint.y;
node.editorPosition = new Vector2 (position.x - xOffset +xoffset1, position.y - yOffset+yoffset1);
}
Dirty ();
// Select the newly added node
if (editorWindow != null)
editorWindow.view.SelectNode (node);
}
public void Connect (Node parent, Node child)
{
if (parent == child)
return;
if (parent.CanConnectChild) {
parent.ConnectChild (child);
// SortChildren(parent);
Dirty ();
} else {
Debug.LogWarning (string.Format ("{0} can't accept child {1}", parent, child));
}
}
public void ConnectKill (Node parent, Node child)
{
if (parent == child)
return;
parent.ConnectKillChild (child);
Dirty ();
}
public void ConnectLeft (NodeBranch parent, Node child)
{
if (parent == child)
return;
if (parent.CanConnectChild) {
parent.ConnectLeftChild (child);
// SortChildren(parent);
Dirty ();
} else {
Debug.LogWarning (string.Format ("{0} can't accept child {1}", parent, child));
}
}
public void ConnectLeftKill (NodeBranch parent, Node child)
{
if (parent == child)
return;
parent.ConnectKillLeftChild (child);
Dirty ();
}
public void ConnectRight (NodeBranch parent, Node child)
{
if (parent == child)
return;
if (parent.CanConnectChild) {
parent.ConnectRightChild (child);
// SortChildren(parent);
Dirty ();
} else {
Debug.LogWarning (string.Format ("{0} can't accept child {1}", parent, child));
}
}
public void ConnectRightKill (NodeBranch parent, Node child)
{
if (parent == child)
return;
parent.ConnectKillRightChild (child);
Dirty ();
}
public void Unparent (Node node)
{
node.Unparent ();
Dirty ();
}
public void DisconnectAll (Node node)
{
node.Disconnect ();
Dirty ();
}
public void Delete (Node node)
{
node.Disconnect ();
behaviorTree.nodes.Remove (node);
DestroyImmediate (node, true);
Dirty ();
}
public void SetEditorPosition (Node node, Vector2 position)
{
node.editorPosition = position;
// SortChildren(node.parent);
Dirty ();
}
// private void SortChildren(Node parent) {
// Composite parentComposite = parent as Composite;
// if (parentComposite != null)
// parentComposite.SortChildren();
// }
}
}