Advertisement
Guest User

Untitled

a guest
Feb 18th, 2020
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.91 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using UnityEditor;
  3. using UnityEditor.SceneManagement;
  4. using UnityEngine;
  5. using Wax.Navigation;
  6.  
  7. namespace Wax
  8. {
  9.     public class WizardGenerateNavmesh : ScriptableWizard
  10.     {
  11.         private const float BOXCHECK_OFFSET = 0.05f;
  12.  
  13.         public Rect area;
  14.         public float minSize = 1.0f, testHeight = 1.0f;
  15.         public LayerMask obstacleLayerMask;
  16.         private NavmeshGeneratorGizmos gizmoHandler;
  17.         private List<Node> nodes;
  18.  
  19.         void OnWizardCreate()
  20.         {
  21.             gizmoHandler.Reset();
  22.             Branch root = new Branch(GenerateNodes(area, gizmoHandler));
  23.             AssignParents(root, null);
  24.             Leaf[] leaves = root.GetLeaves();
  25.             nodes = new List<Node>();
  26.             foreach(Leaf leaf in leaves)
  27.             {
  28.                 if(leaf.Occupied) continue;
  29.                 nodes.Add(new Node(leaf.Rect));
  30.             }
  31.  
  32.             foreach(Node node in nodes)
  33.             {
  34.                 node.SetNeighbours(FindNeighbours(node));
  35.             }
  36.  
  37.             GameObject navmesh = new GameObject("Navmesh");
  38.             navmesh.AddComponent<Navmesh>().SetNodes(nodes.ToArray());
  39.             EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
  40.         }
  41.  
  42.         void OnWizardUpdate()
  43.         {
  44.             if(gizmoHandler == null) return;
  45.             gizmoHandler.SetBaseRect(area);
  46.             gizmoHandler.Height = testHeight;
  47.         }
  48.  
  49.         private INode[] GenerateNodes(Rect area, NavmeshGeneratorGizmos gizmoHandler)
  50.         {
  51.             Vector2 halfSize = area.size * 0.5f;
  52.             Rect qi   = new Rect(area.x + halfSize.x, area.y, halfSize.x, halfSize.y);
  53.             Rect qii  = new Rect(area.x, area.y, halfSize.x, halfSize.y);
  54.             Rect qiii = new Rect(area.x, area.y + halfSize.y, halfSize.x, halfSize.y);
  55.             Rect qiv  = new Rect(area.x + halfSize.x, area.y + halfSize.y, halfSize.x, halfSize.y);
  56.  
  57.             //All of these rects are square, so there's no need to check width and height.
  58.             INode[] nodes = new INode[4];
  59.  
  60.             bool occupied = Physics.CheckBox(new Vector3(qi.center.x, testHeight, qi.center.y), new Vector3(halfSize.x / 2 - BOXCHECK_OFFSET, 1, halfSize.y / 2 - BOXCHECK_OFFSET), Quaternion.identity, obstacleLayerMask);
  61.             if (qi.width > minSize && occupied) nodes[0] = new Branch(GenerateNodes(qi, gizmoHandler));
  62.             else
  63.             {
  64.                 nodes[0] = new Leaf(qi, occupied);
  65.                 gizmoHandler.AddRect((Leaf)nodes[0]);
  66.             }
  67.  
  68.             occupied = Physics.CheckBox(new Vector3(qii.center.x, testHeight, qii.center.y), new Vector3(halfSize.x / 2 - BOXCHECK_OFFSET, 1, halfSize.y / 2 - BOXCHECK_OFFSET), Quaternion.identity, obstacleLayerMask);
  69.             if (qii.width > minSize && occupied) nodes[1] = new Branch(GenerateNodes(qii, gizmoHandler));
  70.             else
  71.             {
  72.                 nodes[1] = new Leaf(qii, occupied);
  73.                 gizmoHandler.AddRect((Leaf)nodes[1]);
  74.             }
  75.  
  76.             occupied = Physics.CheckBox(new Vector3(qiii.center.x, testHeight, qiii.center.y), new Vector3(halfSize.x / 2 - BOXCHECK_OFFSET, 1, halfSize.y / 2 - BOXCHECK_OFFSET), Quaternion.identity, obstacleLayerMask);
  77.             if (qiii.width > minSize && occupied) nodes[2] = new Branch(GenerateNodes(qiii, gizmoHandler));
  78.             else
  79.             {
  80.                 nodes[2] = new Leaf(qiii, occupied);
  81.                 gizmoHandler.AddRect((Leaf)nodes[2]);
  82.             }
  83.  
  84.             occupied = Physics.CheckBox(new Vector3(qiv.center.x, testHeight, qiv.center.y), new Vector3(halfSize.x / 2 - BOXCHECK_OFFSET, 1, halfSize.y / 2 - BOXCHECK_OFFSET), Quaternion.identity, obstacleLayerMask);
  85.             if (qiv.width > minSize && occupied) nodes[3] = new Branch(GenerateNodes(qiv, gizmoHandler));
  86.             else
  87.             {
  88.                 nodes[3] = new Leaf(qiv, occupied);
  89.                 gizmoHandler.AddRect((Leaf)nodes[3]);
  90.             }
  91.  
  92.             return nodes;
  93.         }
  94.  
  95.         private void AssignParents(INode node, Branch parent)
  96.         {
  97.             node.SetParent(parent);
  98.             if(node is Branch)
  99.             {
  100.                 foreach(INode child in ((Branch)node).Children)
  101.                 {
  102.                     AssignParents(child, (Branch)node);
  103.                 }
  104.             }
  105.         }
  106.  
  107.         private NavmeshGeneratorGizmos CreateGizmoHandler()
  108.         {
  109.             GameObject handler = new GameObject("Navmesh Generator Gizmos");
  110.             handler.tag = "EditorOnly";
  111.             return handler.AddComponent<NavmeshGeneratorGizmos>();
  112.         }
  113.  
  114.         private Node[] FindNeighbours(Node node)
  115.         {
  116.             List<Node> neighbours = new List<Node>();
  117.            
  118.             foreach(Node other in nodes)
  119.             {
  120.                 if(other == node) continue;
  121.                 Rect otherRect = other.Rect;
  122.                 Rect thisRect = node.Rect;
  123.  
  124.                 //Difference check
  125.                 if(Mathf.Abs(otherRect.x + otherRect.width - thisRect.x) < float.Epsilon) neighbours.Add(other);
  126.                 else if(Mathf.Abs(thisRect.x + thisRect.width - otherRect.x) < float.Epsilon) neighbours.Add(other);
  127.                 else if(Mathf.Abs(otherRect.y + otherRect.height - thisRect.y) < float.Epsilon) neighbours.Add(other);
  128.                 else if(Mathf.Abs(thisRect.y + thisRect.height - otherRect.y) < float.Epsilon) neighbours.Add(other);
  129.             }
  130.  
  131.             return neighbours.ToArray();
  132.         }
  133.  
  134.         [MenuItem("Window/Navmesh Generator")]
  135.         private static void Create()
  136.         {
  137.             WizardGenerateNavmesh wizard = DisplayWizard<WizardGenerateNavmesh>("Navmesh Generator", "Generate");
  138.             wizard.gizmoHandler = FindObjectOfType<NavmeshGeneratorGizmos>();
  139.             if (wizard.gizmoHandler == null) wizard.gizmoHandler = wizard.CreateGizmoHandler();
  140.         }
  141.  
  142.     }
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement