Advertisement
AnomalousUnderdog

Untitled

Sep 22nd, 2012
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.93 KB | None | 0 0
  1. #if UNITY_EDITOR
  2. using UnityEditor;
  3. using UnityEngine;
  4. using System.IO;
  5. using System.Collections.Generic;
  6. using BehaviourTree;
  7.  
  8. public class BehaviourTreeEditorWindow : EditorWindow
  9. {
  10.     [MenuItem("Window/Behaviour Tree Editor")]
  11.     static void ShowWindow()
  12.     {
  13.         EditorWindow.GetWindow(typeof(BehaviourTreeEditorWindow));
  14.     }
  15.    
  16.     static string[] _comparisonTypeLabels = new string[] {"equal to", "not equal to", "greater than", "greater than or equal to", "lesser than", "lesser than or equal to"};
  17.     static ComparisonType[] _comparisonTypeValues = new ComparisonType[] {ComparisonType.EqualTo, ComparisonType.NotEqualTo, ComparisonType.GreaterThan, ComparisonType.GreaterThanOrEqualTo, ComparisonType.LesserThan, ComparisonType.LesserThanOrEqualTo};
  18.    
  19.     string _lastAssetPath = "";
  20.  
  21.     string _lastBehaviourTreeSelected = "";
  22.     string _currentlyOpenBehaviourTree = "";
  23.  
  24.     Root<IUnit> _currentBehaviourTree = null;
  25.    
  26.     static GUISkin _guiSkin;
  27.     static GUISkin GetSkin()
  28.     {
  29.         if (_guiSkin == null)
  30.         {
  31.             _guiSkin = Resources.Load("BehaviourTreeGuiSkin") as GUISkin;
  32.         }
  33.        
  34.         return _guiSkin;
  35.     }
  36.  
  37.     Vector2 _panOffset = Vector2.zero;
  38.  
  39.     bool IsFolder(string path)
  40.     {
  41.         return ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory);
  42.     }
  43.     void OnSelectionChange()
  44.     {
  45.         string assetTryPath = AssetDatabase.GetAssetPath(Selection.activeObject);
  46.  
  47.         if (assetTryPath.Length > 0)
  48.         {
  49.             string absPath = Application.dataPath;
  50.             absPath = absPath.Substring(0, absPath.LastIndexOf('/')+1); // get rid of "Assets/"
  51.  
  52.             absPath += assetTryPath;
  53.             _lastBehaviourTreeSelected = absPath;
  54.  
  55.             if (IsFolder(assetTryPath))
  56.             {
  57.                 _lastAssetPath = assetTryPath;
  58.             }
  59.             else
  60.             {
  61.                 _lastAssetPath = Path.GetDirectoryName(assetTryPath);
  62.             }
  63.             Repaint();
  64.         }
  65.        
  66.         Debug.Log("Last Asset Path: " + _lastAssetPath);
  67.     }
  68.    
  69.     BehaviourTree.Root<IUnit> PopulateTestValues()
  70.     {
  71.         BehaviourTree.Root<IUnit> root = new BehaviourTree.Root<IUnit>();
  72.         root.Label = "Dragurian Gunner Test AI";
  73.  
  74.         BehaviourTree.Selector<IUnit> sel1 = new BehaviourTree.Selector<IUnit>();
  75.         sel1.Label = "";
  76.  
  77.         BehaviourTree.Sequence<IUnit> retSeq = new BehaviourTree.Sequence<IUnit>();
  78.         retSeq.Label = "Retreat";
  79.         retSeq.Remarks = "Should I retreat now?";
  80.  
  81.         BehaviourTree.MyHealthPercentCheck<IUnit> myHealth = new BehaviourTree.MyHealthPercentCheck<IUnit>();
  82.         myHealth.Label = "health low?";
  83.         myHealth.Comparison = BehaviourTree.ComparisonType.LesserThanOrEqualTo;
  84.         myHealth.Value = 0.25f;
  85.        
  86.         BehaviourTree.Retreat<IUnit> ret = new BehaviourTree.Retreat<IUnit>();
  87.         ret.Label = "retreat!";
  88.         ret.CheckForEnemiesDistance = 10.0f;
  89.         ret.EnemiesNearEachOtherDistance = 10.0f;
  90.         ret.DistanceToFlee = 20.0f;
  91.        
  92.        
  93.        
  94.         BehaviourTree.Sequence<IUnit> lungeSeq = new BehaviourTree.Sequence<IUnit>();
  95.         lungeSeq.Label = "Attack";
  96.         lungeSeq.Remarks = "Only melee attack for now.";
  97.        
  98.         BehaviourTree.AssignNearestEnemyAsTarget<IUnit> nearestEnemy = new BehaviourTree.AssignNearestEnemyAsTarget<IUnit>();
  99.         nearestEnemy.Label = "find nearest enemy!";
  100.        
  101.         //BehaviourTree.HasSufficientStaminaToDo canLunge = new BehaviourTree.HasSufficientStaminaToDo();
  102.         //canLunge.Label = "CanLungeNow?";
  103.        
  104.        
  105.         BehaviourTree.GetInMeleeRangeOfTarget<IUnit> getInLungeRange = new BehaviourTree.GetInMeleeRangeOfTarget<IUnit>(); // can return running
  106.         getInLungeRange.Label = "get in lunge range!";
  107.         getInLungeRange.ActionName = "Strike";
  108.         getInLungeRange.AttackName = "Lunge";
  109.        
  110.         BehaviourTree.GetInMeleeRangeOfTarget<IUnit> getInLungeRange2 = new BehaviourTree.GetInMeleeRangeOfTarget<IUnit>(); // can return running
  111.         getInLungeRange2.Label = "get in lunge range!";
  112.         getInLungeRange2.ActionName = "Strike";
  113.         getInLungeRange2.AttackName = "Lunge";
  114.        
  115.         BehaviourTree.GetInMeleeRangeOfTarget<IUnit> getInLungeRange3 = new BehaviourTree.GetInMeleeRangeOfTarget<IUnit>(); // can return running
  116.         getInLungeRange3.Label = "get in lunge range!";
  117.         getInLungeRange3.ActionName = "Strike";
  118.         getInLungeRange3.AttackName = "Lunge";
  119.        
  120.         BehaviourTree.DoActionOnTarget<IUnit> strike = new BehaviourTree.DoActionOnTarget<IUnit>();
  121.         strike.Label = "strike!";
  122.         strike.ActionName = "Strike";
  123.        
  124.         BehaviourTree.DoActionOnTarget<IUnit> strike2 = new BehaviourTree.DoActionOnTarget<IUnit>();
  125.         strike2.Label = "strike!";
  126.         strike2.ActionName = "Strike";
  127.        
  128.         BehaviourTree.EnoughStaminaTo<IUnit> canGetInRange = new BehaviourTree.EnoughStaminaTo<IUnit>();
  129.         canGetInRange.Label = "enough stamina to";
  130.        
  131.         BehaviourTree.EnoughStaminaTo<IUnit> canLunge = new BehaviourTree.EnoughStaminaTo<IUnit>();
  132.         canLunge.Label = "enough stamina to";
  133.        
  134.        
  135.         BehaviourTree.PassTurn<IUnit> passTurn = new BehaviourTree.PassTurn<IUnit>();
  136.         passTurn.Label = "pass turn!";
  137.        
  138.        
  139.         BehaviourTree.Sequence<IUnit> shootSeq = new BehaviourTree.Sequence<IUnit>();
  140.         shootSeq.Label = "ToShoot";
  141.        
  142.        
  143.        
  144.        
  145.        
  146.         // test decorators:
  147.        
  148.         BehaviourTree.EnoughStaminaTo<IUnit> d1 = new BehaviourTree.EnoughStaminaTo<IUnit>();
  149.         d1.Label = "Inverse";
  150.        
  151.         BehaviourTree.EnoughStaminaTo<IUnit> d2 = new BehaviourTree.EnoughStaminaTo<IUnit>();
  152.         d2.Label = "Semaphore B";
  153.        
  154.         d2.Adopt(d1);
  155.        
  156.        
  157.        
  158.         BehaviourTree.EnoughStaminaTo<IUnit> d3 = new BehaviourTree.EnoughStaminaTo<IUnit>();
  159.         d3.Label = "Control Target";
  160.        
  161.        
  162.         BehaviourTree.EnoughStaminaTo<IUnit> d4 = new BehaviourTree.EnoughStaminaTo<IUnit>();
  163.         d4.Label = "Time Delay";
  164.        
  165.         BehaviourTree.EnoughStaminaTo<IUnit> d5 = new BehaviourTree.EnoughStaminaTo<IUnit>();
  166.         d5.Label = "Semaphore A";
  167.        
  168.         d5.Adopt(d4);
  169.         d4.Adopt(d3);
  170.        
  171.         root.Adopt(sel1);
  172.        
  173.         //sel1.Adopt(retSeq);
  174.        
  175.         sel1.Adopt(d5);
  176.         d3.Adopt(retSeq);
  177.        
  178.         //retSeq.Adopt(myHealth);
  179.         retSeq.Adopt(d2);
  180.         d1.Adopt(myHealth);
  181.         retSeq.Adopt(ret);
  182.        
  183.         sel1.Adopt(lungeSeq);
  184.        
  185.         lungeSeq.Adopt(nearestEnemy);
  186.        
  187.         BehaviourTree.Selector<IUnit> lungeOrCloseIn = new BehaviourTree.Selector<IUnit>();
  188.         lungeOrCloseIn.Label = "";
  189.         BehaviourTree.Sequence<IUnit> actualLungeSeq = new BehaviourTree.Sequence<IUnit>();
  190.         actualLungeSeq.Label = "Lunge";
  191.         actualLungeSeq.Remarks = "Checks first if unit has enough stamina to close in *and* do the attack. Bails out if it can't do both in this turn.";
  192.        
  193.         BehaviourTree.Sequence<IUnit> closeInSeq = new BehaviourTree.Sequence<IUnit>();
  194.         closeInSeq.Label = "Close in";
  195.         closeInSeq.Remarks = "Just close in on the enemy if can't do anything useful. Later on, I'll add higher priority behaviours like try ranged attack (if the Lunge failed).";
  196.        
  197.        
  198.        
  199.        
  200.        
  201.         lungeSeq.Adopt(lungeOrCloseIn);
  202.        
  203.         lungeOrCloseIn.Adopt(actualLungeSeq);
  204.         lungeOrCloseIn.Adopt(closeInSeq);
  205.        
  206.         canGetInRange.Adopt(getInLungeRange);
  207.         canLunge.Adopt(strike);
  208.        
  209.         //canLunge.Adopt(getInLungeRange);
  210.         //canLunge.Adopt(strike);
  211.        
  212.         actualLungeSeq.Adopt(canGetInRange);
  213.         actualLungeSeq.Adopt(canLunge);
  214.         actualLungeSeq.Adopt(getInLungeRange2);
  215.         actualLungeSeq.Adopt(strike2);
  216.        
  217.         closeInSeq.Adopt(getInLungeRange3);
  218.         closeInSeq.Adopt(passTurn);
  219.        
  220.         return root;
  221.     }
  222.    
  223.     Rect _windowRect = new Rect(0, 0, 100, 100);
  224.    
  225.     void DrawColorPickerWindow(int windowID)
  226.     {
  227.         Debug.Log("in window");
  228.         GUI.Box(new Rect(0,0,20, 20), "");
  229.         /*GUI.DragWindow(new Rect(0, 0, 10000, 20));
  230.  
  231.         GUIStyle windowStyle = GUI.skin.window;
  232.  
  233.         GUI.BeginGroup(new Rect(windowStyle.padding.left, windowStyle.padding.top, _windowRect.width-windowStyle.padding.horizontal, _windowRect.height-windowStyle.padding.vertical));
  234.         if (ColorPicker.DrawControls(new Vector2(10, 100)))
  235.         {
  236.             Repaint();
  237.         }
  238.         GUI.EndGroup();*/
  239.     }
  240.    
  241.     void OnGUI()
  242.     {
  243.         _windowRect = GUI.Window(1, _windowRect, DrawColorPickerWindow, "Color Picker");
  244.         wantsMouseMove = true;
  245.        
  246.         GUI.skin = GetSkin();
  247.         GUI.SetNextControlName("Unfocuser");
  248.         GUI.TextField(new Rect(10, -50, 100, 20), "");
  249.        
  250.         if (_currentBehaviourTree != null)
  251.         {
  252.             DrawBehaviourTreeControl(_currentBehaviourTree);
  253.         }
  254.         EditorGUILayout.BeginVertical();
  255.         EditorGUILayout.BeginHorizontal();
  256.         if (GUILayout.Button("New..."))
  257.         {
  258.             GUI.FocusControl("Unfocuser");
  259.  
  260.             //_currentBehaviourTree = new Root();
  261.             _currentBehaviourTree = PopulateTestValues();
  262.             _currentlyOpenBehaviourTree = "";
  263.         }
  264.         if (_currentBehaviourTree != null && GUILayout.Button("Save as..."))
  265.         {
  266.             string finalPath = "";
  267.             string savepath = "";
  268.             if (_lastAssetPath.Length > 0)
  269.             {
  270.                 savepath = EditorUtility.SaveFilePanel("Save Behaviour Tree file", _lastAssetPath, "New Behaviour Tree", "txt");
  271.                 finalPath = savepath;
  272.             }
  273.             else
  274.             {
  275.                 savepath = EditorUtility.SaveFilePanelInProject("Save Behaviour Tree file", "New Behaviour Tree", "txt", "");
  276.                 finalPath = Application.dataPath;
  277.                 finalPath = finalPath.Substring(0, finalPath.LastIndexOf('/')+1); // get rid of "Assets/"
  278.                 finalPath += savepath;
  279.             }
  280.  
  281.             if (finalPath.Length > 0)
  282.             {
  283.                 //Debug.Log("save to: " + finalPath);
  284.                 Root<IUnit>.SaveToLocal(finalPath, _currentBehaviourTree);
  285.                 _currentlyOpenBehaviourTree = finalPath;
  286.  
  287.                 AssetDatabase.ImportAsset(savepath, ImportAssetOptions.ForceUpdate);
  288.             }
  289.         }
  290.         EditorGUILayout.EndHorizontal();
  291.  
  292.         if (GUILayout.Button("Open: " + Path.GetFileName(_lastBehaviourTreeSelected)))
  293.         {
  294.             GUI.FocusControl("Unfocuser");
  295.  
  296.             _currentBehaviourTree = Root<IUnit>.LoadFromLocal(_lastBehaviourTreeSelected);
  297.             if (_currentBehaviourTree != null)
  298.             {
  299.                 _currentlyOpenBehaviourTree = _lastBehaviourTreeSelected;
  300.             }
  301.             else
  302.             {
  303.                 Debug.LogError("Behaviour Tree Editor: Error loading: " + _lastBehaviourTreeSelected);
  304.             }
  305.         }
  306.         if (_currentBehaviourTree != null && _currentlyOpenBehaviourTree == _lastBehaviourTreeSelected && GUILayout.Button("Save: " + Path.GetFileName(_lastBehaviourTreeSelected)))
  307.         {
  308.             Root<IUnit>.SaveToLocal(_lastBehaviourTreeSelected, _currentBehaviourTree);
  309.             AssetDatabase.Refresh();
  310.             //AssetDatabase.ImportAsset(_lastBehaviourTreeSelected, ImportAssetOptions.ForceUpdate);
  311.         }
  312.         EditorGUILayout.EndVertical();
  313.        
  314.        
  315.     }
  316.    
  317.     Node<IUnit> _lastDraggedNode = null;
  318.  
  319.     public void DrawBehaviourTreeControl(Root<IUnit> tree)
  320.     {
  321.         Event e = Event.current;
  322.        
  323.         //if (e.control)
  324.         //{
  325.         //  EditorGUIUtility.AddCursorRect(new Rect(0,0,Mathf.Infinity,Mathf.Infinity), MouseCursor.MoveArrow);
  326.         //  Repaint();
  327.         //}
  328.         //else
  329.         //{
  330.         //  EditorGUIUtility.AddCursorRect(new Rect(0,0,Mathf.Infinity,Mathf.Infinity), MouseCursor.Arrow);
  331.         //  Repaint();
  332.         //}
  333.        
  334.         if (e.isMouse && e.type == EventType.MouseDrag && (((e.button == 0 || e.button > 2) && e.control) || e.button == 1))
  335.         {
  336.             _panOffset += e.delta;
  337.             Repaint();
  338.         }
  339.         if (e.isKey && e.keyCode == KeyCode.F12)
  340.         {
  341.             _panOffset = Vector2.zero;
  342.             Repaint();
  343.         }
  344.         GUI.BeginGroup(new Rect(_panOffset.x, _panOffset.y, Mathf.Infinity, Mathf.Infinity));
  345.        
  346.         Vector2 rootPos = new Vector2(tree.GetSelfDrawSize(GUI.skin).x * 0.5f, 0);
  347.        
  348.         Node<IUnit>.DragOperation dragOperation = new Node<IUnit>.DragOperation();
  349.        
  350.         tree.Draw(rootPos, this, 0, 0, dragOperation);
  351.        
  352.         // draw dragged node in 50% transparent
  353.         if (dragOperation.DraggingNode != null)
  354.         {
  355.             Vector2 m = e.mousePosition;
  356.            
  357.             Color old = GUI.color;
  358.             Color transp = old;
  359.             transp.a = 0.5f;
  360.             GUI.color = transp;
  361.            
  362.             dragOperation.DraggingNode.Draw(m, this, 0, 0, null);
  363.             _lastDraggedNode = dragOperation.DraggingNode;
  364.            
  365.             GUI.color = old;
  366.            
  367.             Repaint();
  368.         }
  369.        
  370.         if (e.type == EventType.MouseUp &&
  371.             _lastDraggedNode != null && // something dragged
  372.             dragOperation.DroppedNode != null && // somewhere to drop
  373.             dragOperation.DroppedNode.CanHaveChildren && // drop allowed
  374.             (_lastDraggedNode != dragOperation.DroppedNode)) // not dropping to self
  375.         {
  376.             Debug.Log("\"" + _lastDraggedNode.Label + "\" dropped to \"" + dragOperation.DroppedNode.Label + "\" at " + dragOperation.DroppedPos);
  377.                
  378.             _lastDraggedNode.Detach();
  379.             dragOperation.DroppedNode.UserAttachNode(_lastDraggedNode, dragOperation.DroppedPos);
  380.             _lastDraggedNode = null;
  381.         }
  382.        
  383.         GUI.EndGroup();
  384.     }
  385. }
  386.  
  387. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement