public void OnSceneGUI () { // Update drawer if (drawer != null) drawer.editGrid = editGrid; // Stop if needed if (!editGrid) { didUpdate = false; return; } // Create grid if (grid == null || grid.Length != MapperWindowEditor.gridSize) { grid = new Cell[MapperWindowEditor.gridSize][]; for (int i = 0; i < MapperWindowEditor.gridSize; i++) grid [i] = new Cell[MapperWindowEditor.gridSize]; } // Prepare holders if (mapper == null) { mapper = (Mapper)target; } if (drawer == null) { drawer = mapper.gameObject.GetComponent<MapperEditorDrawer> (); } drawer.editingGrid = grid; // Update Scene if (!didUpdate) { mapper.ComputeTileSize (SpaceState.Editor, mapper.collider.bounds.min, mapper.collider.bounds.max, MapperWindowEditor.gridSize, MapperWindowEditor.gridSize); drawer.tileSize.Set (SpaceState.Editor.tileSize.x, SpaceState.Editor.tileSize.y); drawer.zero.Set (SpaceState.Editor.floorMin.x, SpaceState.Editor.floorMin.z); didUpdate = true; } // Raycast Event current = Event.current; if (current != null && EventType.KeyDown == current.type) { Ray ray = HandleUtility.GUIPointToWorldRay (current.mousePosition); RaycastHit hit; if (Physics.Raycast (ray, out hit, Mathf.Infinity, 1 << LayerMask.NameToLayer ("Floor"))) { if (hit.transform.CompareTag ("Floor")) { Vector2 pos = new Vector2 ((hit.point.x - hit.collider.bounds.min.x) / SpaceState.Editor.tileSize.x, (hit.point.z - hit.collider.bounds.min.x) / SpaceState.Editor.tileSize.y); Cell c = grid [(int)pos.x] [(int)pos.y]; if (c == null) { c = new Cell (); grid [(int)pos.x] [(int)pos.y] = c; } switch (current.keyCode) { case KeyCode.Alpha0: grid [(int)pos.x] [(int)pos.y] = null; break; case KeyCode.Alpha1: c.safe = true; break; case KeyCode.Alpha2: c.blocked = true; break; case KeyCode.Alpha3: c.noisy = true; break; case KeyCode.Alpha4: c.waypoint = true; break; case KeyCode.U: c.cluster = 0; break; case KeyCode.Alpha6: c.cluster |= 1; break; case KeyCode.Alpha7: c.cluster |= 2; break; case KeyCode.Alpha8: c.cluster |= 4; break; case KeyCode.Alpha9: c.cluster |= 8; break; case KeyCode.Keypad4: c.cluster |= 8; break; case KeyCode.Keypad5: c.cluster |= 16; break; case KeyCode.Keypad6: c.cluster |= 32; break; case KeyCode.Keypad7: c.cluster |= 64; break; case KeyCode.Keypad8: c.cluster |= 128; break; case KeyCode.Keypad9: c.cluster |= 256; break; } SceneView.RepaintAll (); } } } } // OnSceneGui
void OnGUI() { #region Pre-Init // Wait for the floor to be set and initialize the drawer and the mapper if (floor != null) { if (floor.collider == null) { Debug.LogWarning ("Floor has no valid collider, game object ignored."); floor = null; } else { drawer = floor.gameObject.GetComponent<MapperEditorDrawer> (); if (drawer == null) { drawer = floor.gameObject.AddComponent<MapperEditorDrawer> (); drawer.hideFlags = HideFlags.HideInInspector; } } if (mapper == null) { mapper = floor.GetComponent<Mapper> (); if (mapper == null) mapper = floor.AddComponent<Mapper> (); mapper.hideFlags = HideFlags.None; } } #endregion // ---------------------------------- scrollPos = EditorGUILayout.BeginScrollView (scrollPos); #region 1. Map EditorGUILayout.LabelField ("1. Map"); playerPrefab = (GameObject)EditorGUILayout.ObjectField ("Player Prefab", playerPrefab, typeof(GameObject), false); floor = (GameObject)EditorGUILayout.ObjectField ("Floor", floor, typeof(GameObject), true); gridSize = EditorGUILayout.IntSlider ("Grid size", gridSize, 10, 300); if (GUILayout.Button ((MapperEditor.editGrid ? "Finish Editing" : "Edit Grid"))) { if (floor != null) { MapperEditor.editGrid = !MapperEditor.editGrid; Selection.activeGameObject = mapper.gameObject; } } EditorGUILayout.LabelField (""); #endregion // ---------------------------------- #region 2. Units EditorGUILayout.LabelField ("2. Units"); playerDPS = EditorGUILayout.Slider("Player DPS", playerDPS, 0.1f, 100f); if (GUILayout.Button ("Store Positions")) { StorePositions (); } EditorGUILayout.LabelField (""); #endregion // ---------------------------------- #region 3. Map Computation EditorGUILayout.LabelField ("3. Map Computation"); timeSamples = EditorGUILayout.IntSlider ("Time samples", timeSamples, 1, 10000); stepSize = EditorGUILayout.Slider ("Step size", stepSize, 0.01f, 1f); stepInTicks = ((long)(stepSize * 10000000L)); ticksBehind = EditorGUILayout.IntSlider (new GUIContent ("Ticks behind", "Number of ticks that the FoV will remain seen after the enemy has no visibility on that cell (prevents noise/jitter like behaviours)"), ticksBehind, 0, 100); if (GUILayout.Button ("Precompute Maps")) { //Find this is the view if (playerPrefab == null) { playerPrefab = GameObject.Find ("Player"); } if (floor == null) { floor = (GameObject)GameObject.Find ("Floor"); if (mapper == null) { mapper = floor.GetComponent<Mapper> (); if (mapper == null) mapper = floor.AddComponent<Mapper> (); mapper.hideFlags = HideFlags.None; } drawer = floor.gameObject.GetComponent<MapperEditorDrawer> (); if (drawer == null) { drawer = floor.gameObject.AddComponent<MapperEditorDrawer> (); drawer.hideFlags = HideFlags.HideInInspector; } } if (!simulated) { StorePositions (); simulated = true; } Cell[][] baseMap = null; if (MapperEditor.grid != null) { Cell[][] obstacles = mapper.ComputeObstacles (); baseMap = new Cell[gridSize][]; for (int x = 0; x < gridSize; x++) { baseMap [x] = new Cell[gridSize]; for (int y = 0; y < gridSize; y++) { baseMap [x] [y] = MapperEditor.grid [x] [y] == null ? obstacles [x] [y] : MapperEditor.grid [x] [y]; } } } original = mapper.PrecomputeMaps (SpaceState.Editor, floor.collider.bounds.min, floor.collider.bounds.max, gridSize, gridSize, timeSamples, stepSize, ticksBehind, baseMap); drawer.fullMap = original; float maxSeenGrid; drawer.seenNeverSeen = Analyzer.ComputeSeenValuesGrid (original, out maxSeenGrid); drawer.seenNeverSeenMax = maxSeenGrid; drawer.tileSize = SpaceState.Editor.tileSize; drawer.zero.Set (floor.collider.bounds.min.x, floor.collider.bounds.min.z); ResetAI (); previous = DateTime.Now; } EditorGUILayout.LabelField (""); #endregion // ---------------------------------- #region 4. Path EditorGUILayout.LabelField ("4. Path"); start = (GameObject)EditorGUILayout.ObjectField ("Start", start, typeof(GameObject), true); end = (GameObject)EditorGUILayout.ObjectField ("End", end, typeof(GameObject), true); attemps = EditorGUILayout.IntSlider ("Attempts", attemps, 1000, 100000); iterations = EditorGUILayout.IntSlider ("Iterations", iterations, 1, 1500); randomSeed = EditorGUILayout.IntSlider("Random Seed", randomSeed, -1, 10000); smoothPath = EditorGUILayout.Toggle ("Smooth path", smoothPath); simulateCombat = EditorGUILayout.Toggle ("Simulate combat", simulateCombat); if (GUILayout.Button ("(WIP) Compute 3D A* Path")) { float playerSpeed = GameObject.FindGameObjectWithTag ("AI").GetComponent<Player> ().speed; //Check the start and the end and get them from the editor. if (start == null) { start = GameObject.Find ("Start"); } if (end == null) { end = GameObject.Find ("End"); } startX = (int)((start.transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x); startY = (int)((start.transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y); endX = (int)((end.transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x); endY = (int)((end.transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y); paths.Clear (); deaths.Clear (); ClearPathsRepresentation (); arrangedByCrazy = arrangedByDanger = arrangedByDanger3 = arrangedByDanger3Norm = arrangedByLength = arrangedByLoS = arrangedByLoS3 = arrangedByLoS3Norm = arrangedByTime = arrangedByVelocity = null; Exploration.DavAStar3d astar3d = new DavAStar3d(); List<Node> nodes = astar3d.Compute(startX, startY, endX, endY, original, playerSpeed); if (nodes.Count > 0) { paths.Add (new Path (nodes)); toggleStatus.Add (paths.Last (), true); paths.Last ().color = new Color (UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f)); } } if (GUILayout.Button ("Compute Path")) { float playerSpeed = GameObject.FindGameObjectWithTag ("AI").GetComponent<Player> ().speed; float playerMaxHp = GameObject.FindGameObjectWithTag ("AI").GetComponent<Player> ().maxHp; //Check the start and the end and get them from the editor. if (start == null) { start = GameObject.Find ("Start"); } if (end == null) { end = GameObject.Find ("End"); } paths.Clear (); deaths.Clear (); ClearPathsRepresentation (); arrangedByCrazy = arrangedByDanger = arrangedByDanger3 = arrangedByDanger3Norm = arrangedByLength = arrangedByLoS = arrangedByLoS3 = arrangedByLoS3Norm = arrangedByTime = arrangedByVelocity = null; // Prepare start and end position startX = (int)((start.transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x); startY = (int)((start.transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y); endX = (int)((end.transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x); endY = (int)((end.transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y); GameObject[] hps = GameObject.FindGameObjectsWithTag("HealthPack"); HealthPack[] packs = new HealthPack[hps.Length]; for (int i = 0; i < hps.Length; i++) { packs[i] = hps[i].GetComponent<HealthPack>(); packs[i].posX = (int)((packs[i].transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x); packs[i].posZ = (int)((packs[i].transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y); } // Update the parameters on the RRT class rrt.min = floor.collider.bounds.min; rrt.tileSizeX = SpaceState.Editor.tileSize.x; rrt.tileSizeZ = SpaceState.Editor.tileSize.y; rrt.enemies = SpaceState.Editor.enemies; rrt.packs = packs; rrt.simulateCombat = simulateCombat; int seed = randomSeed; if (randomSeed != -1) UnityEngine.Random.seed = randomSeed; else { DateTime now = DateTime.Now; seed = now.Millisecond + now.Second + now.Minute + now.Hour + now.Day + now.Month+ now.Year; UnityEngine.Random.seed = seed; } List<Node> nodes = null; for (int it = 0; it < iterations; it++) { // Make a copy of the original map fullMap = new Cell[original.Length][][]; for (int t = 0; t < original.Length; t++) { fullMap[t] = new Cell[original[0].Length][]; for (int x = 0; x < original[0].Length; x++) { fullMap[t][x] = new Cell[original[0][0].Length]; for (int y = 0; y < original[0][0].Length; y++) fullMap[t][x][y] = original[t][x][y].Copy(); } } // Use the copied map so the RRT can modify it foreach (Enemy e in SpaceState.Editor.enemies) { for (int t = 0; t < original.Length; t++) for (int x = 0; x < original[0].Length; x++) for (int y = 0; y < original[0][0].Length; y++) if (e.seenCells[t][x][y] != null) e.seenCells[t][x][y] = fullMap[t][x][y]; // TODO: Need to make a backup of the enemies positions, rotations and forwards } // We have this try/catch block here to account for the issue that we don't solve when we find a path when t is near the limit try { nodes = rrt.Compute (startX, startY, endX, endY, attemps, stepSize, playerMaxHp, playerSpeed, playerDPS, fullMap, smoothPath); // Did we found a path? if (nodes.Count > 0) { paths.Add (new Path (nodes)); toggleStatus.Add (paths.Last (), true); paths.Last ().color = new Color (UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f)); } // Grab the death list foreach (List<Node> deathNodes in rrt.deathPaths) { deaths.Add(new Path(deathNodes)); } } catch (Exception e) { Debug.LogWarning("Skip errored calculated path"); Debug.LogException(e); // This can happen in two different cases: // In line 376 by having a duplicate node being picked (coincidence picking the EndNode as visiting but the check is later on) // We also cant just bring the check earlier since there's data to be copied (really really rare cases) // The other case is yet unkown, but it's a conicidence by trying to insert a node in the tree that already exists (really rare cases) } } // Set the map to be drawn drawer.fullMap = fullMap; ComputeHeatMap (paths, deaths); // Compute the summary about the paths and print it String summary = "Summary:\n"; summary += "Seed used:" + seed; summary += "\nSuccessful paths found: " + paths.Count; summary += "\nDead paths: " + deaths.Count; // How many paths killed how many enemies Dictionary<int, int> map = new Dictionary<int, int>(); for (int i = 0; i <= SpaceState.Editor.enemies.Length; i++) map.Add(i, 0); foreach (Path p in paths) { int killed = 0; foreach (Node n in p.points) if (n.died != null) killed++; if (map.ContainsKey(killed)) map[killed]++; else map.Add(killed, 1); } foreach (int k in map.Keys) { summary += "\n" + map[k] + " paths killed " + k + " enemies"; } // Debug.Log(summary); } if (GUILayout.Button ("(DEBUG) Export Paths")) { List<Path> all = new List<Path>(); all.AddRange(paths); all.AddRange(deaths); PathBulk.SavePathsToFile ("pathtest.xml", all); } if (GUILayout.Button ("(DEBUG) Import Paths")) { paths.Clear (); ClearPathsRepresentation (); List<Path> pathsImported = PathBulk.LoadPathsFromFile ("pathtest.xml"); foreach (Path p in pathsImported) { if (p.points.Last().playerhp <= 0) { deaths.Add(p); } else { p.name = "Imported " + (++imported); p.color = new Color (UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f)); toggleStatus.Add (p, true); } } ComputeHeatMap (paths, deaths); SetupArrangedPaths (paths); } EditorGUILayout.LabelField (""); #endregion // ---------------------------------- #region 5. Visualization EditorGUILayout.LabelField ("5. Visualization"); timeSlice = EditorGUILayout.IntSlider ("Time", timeSlice, 0, timeSamples - 1); drawMap = EditorGUILayout.Toggle ("Draw map", drawMap); drawNeverSeen = EditorGUILayout.Toggle ("- Draw safe places", drawNeverSeen); drawFoVOnly = EditorGUILayout.Toggle ("- Draw only fields of view", drawFoVOnly); drawHeatMap = EditorGUILayout.Toggle ("- Draw heat map", drawHeatMap); drawCombatHeatMap = EditorGUILayout.Toggle ("-> Draw combat heat map", drawCombatHeatMap); drawHeatMap3d = EditorGUILayout.Toggle ("-> Draw heat map 3d", drawHeatMap3d); drawDeathHeatMap = EditorGUILayout.Toggle ("-> Draw death heat map", drawDeathHeatMap); drawDeathHeatMap3d = EditorGUILayout.Toggle ("--> Draw 3d death heat map", drawDeathHeatMap3d); drawPath = EditorGUILayout.Toggle ("Draw path", drawPath); drawCombatLines = EditorGUILayout.Toggle ("Draw combat lines", drawCombatLines); if (drawer != null) { drawer.heatMap = null; drawer.heatMap3d = null; drawer.deathHeatMap = null; drawer.deathHeatMap3d = null; drawer.combatHeatMap = null; if (drawHeatMap) { if (drawCombatHeatMap) drawer.combatHeatMap = combatHeatMap; else if (drawHeatMap3d) drawer.heatMap3d = heatMap3d; else if (drawDeathHeatMap) { if (drawDeathHeatMap3d) drawer.deathHeatMap3d = deathHeatMap3d; else drawer.deathHeatMap = deathHeatMap; } else drawer.heatMap = heatMap; } } EditorGUILayout.LabelField (""); if (GUILayout.Button (playing ? "Stop" : "Play")) { playing = !playing; } EditorGUILayout.LabelField (""); /*if (GUILayout.Button ("Batch computation")) { BatchComputing (); }*/ #endregion // ---------------------------------- #region 6. Paths EditorGUILayout.LabelField ("6. Paths"); EditorGUILayout.LabelField (""); crazySeconds = EditorGUILayout.Slider ("Crazy seconds window", crazySeconds, 0f, 10f); if (GUILayout.Button ("Analyze paths")) { ClearPathsRepresentation (); // Setup paths names int i = 1; foreach (Path path in paths) { path.name = "Path " + (i++); path.color = new Color (UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f)); toggleStatus.Add (path, true); path.ZeroValues (); } // Analyze paths Analyzer.PreparePaths (paths); //Analyzer.ComputePathsTimeValues (paths); //Analyzer.ComputePathsLengthValues (paths); //Analyzer.ComputePathsVelocityValues (paths); //Analyzer.ComputePathsLoSValues (paths, SpaceState.Editor.enemies, floor.collider.bounds.min, SpaceState.Editor.tileSize.x, SpaceState.Editor.tileSize.y, original, drawer.seenNeverSeen, drawer.seenNeverSeenMax); Analyzer.ComputePathsDangerValues (paths, SpaceState.Editor.enemies, floor.collider.bounds.min, SpaceState.Editor.tileSize.x, SpaceState.Editor.tileSize.y, original, drawer.seenNeverSeen, drawer.seenNeverSeenMax); //Analyzer.ComputeCrazyness (paths, original, Mathf.FloorToInt (crazySeconds / stepSize)); //Analyzer.ComputePathsVelocityValues (paths); SetupArrangedPaths (paths); } if (GUILayout.Button ("(DEBUG) Export Analysis")) { XmlSerializer ser = new XmlSerializer (typeof(MetricsRoot), new Type[] { typeof(PathResults), typeof(PathValue), typeof(Value) }); MetricsRoot root = new MetricsRoot (); foreach (Path path in paths) { root.everything.Add (new PathResults (path, Analyzer.pathMap [path])); } using (FileStream stream = new FileStream ("pathresults.xml", FileMode.Create)) { ser.Serialize (stream, root); stream.Flush (); stream.Close (); } } if (GUILayout.Button ("(DEBUG) Compute clusters")) { ComputeClusters (); } #region Paths values display seeByTime = EditorGUILayout.Foldout (seeByTime, "Paths by Time"); if (seeByTime && arrangedByTime != null) { for (int i = 0; i < arrangedByTime.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByTime [i].name, arrangedByTime [i].time); toggleStatus [arrangedByTime [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByTime [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByTime [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } seeByLength = EditorGUILayout.Foldout (seeByLength, "Paths by Length"); if (seeByLength && arrangedByLength != null) { for (int i = 0; i < arrangedByLength.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByLength [i].name, arrangedByLength [i].length2d); toggleStatus [arrangedByLength [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByLength [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByLength [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } seeByDanger = EditorGUILayout.Foldout (seeByDanger, "Paths by Danger (A*)"); if (seeByDanger && arrangedByDanger != null) { for (int i = 0; i < arrangedByDanger.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByDanger [i].name, arrangedByDanger [i].danger); toggleStatus [arrangedByDanger [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByDanger [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByDanger [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } seeByDanger3 = EditorGUILayout.Foldout (seeByDanger3, "Paths by Danger 3 (A*)"); if (seeByDanger3 && arrangedByDanger3 != null) { for (int i = 0; i < arrangedByDanger3.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByDanger3 [i].name, arrangedByDanger3 [i].danger3); toggleStatus [arrangedByDanger3 [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByDanger3 [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByDanger3 [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } seeByDanger3Norm = EditorGUILayout.Foldout (seeByDanger3Norm, "Paths by Danger 3 (A*) (normalized)"); if (seeByDanger3Norm && arrangedByDanger3Norm != null) { for (int i = 0; i < arrangedByDanger3Norm.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByDanger3Norm [i].name, arrangedByDanger3Norm [i].danger3Norm); toggleStatus [arrangedByDanger3Norm [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByDanger3Norm [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByDanger3Norm [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } seeByLoS = EditorGUILayout.Foldout (seeByLoS, "Paths by Line of Sight (FoV)"); if (seeByLoS && arrangedByLoS != null) { for (int i = 0; i < arrangedByLoS.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByLoS [i].name, arrangedByLoS [i].los); toggleStatus [arrangedByLoS [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByLoS [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByLoS [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } seeByLoS3 = EditorGUILayout.Foldout (seeByLoS3, "Paths by Line of Sight 3 (FoV)"); if (seeByLoS3 && arrangedByLoS3 != null) { for (int i = 0; i < arrangedByLoS3.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByLoS3 [i].name, arrangedByLoS3 [i].los3); toggleStatus [arrangedByLoS3 [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByLoS3 [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByLoS3 [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } seeByLoS3Norm = EditorGUILayout.Foldout (seeByLoS3Norm, "Paths by Line of Sight 3 (FoV) (normalized)"); if (seeByLoS3Norm && arrangedByLoS3Norm != null) { for (int i = 0; i < arrangedByLoS3Norm.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByLoS3Norm [i].name, arrangedByLoS3Norm [i].los3Norm); toggleStatus [arrangedByLoS3Norm [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByLoS3Norm [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByLoS3Norm [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } seeByCrazy = EditorGUILayout.Foldout (seeByCrazy, "Paths by Crazyness"); if (seeByCrazy && arrangedByCrazy != null) { for (int i = 0; i < arrangedByCrazy.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByCrazy [i].name, arrangedByCrazy [i].crazy); toggleStatus [arrangedByCrazy [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByCrazy [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByCrazy [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } seeByVelocity = EditorGUILayout.Foldout (seeByVelocity, "Paths by Velocity Changes"); if (seeByVelocity && arrangedByVelocity != null) { for (int i = 0; i < arrangedByVelocity.Count; i++) { EditorGUILayout.BeginHorizontal (); EditorGUILayout.FloatField (arrangedByVelocity [i].name, arrangedByVelocity [i].velocity); toggleStatus [arrangedByVelocity [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByVelocity [i]], GUILayout.MaxWidth (20f)); EditorGUILayout.ColorField (arrangedByVelocity [i].color, GUILayout.MaxWidth (40f)); EditorGUILayout.EndHorizontal (); } } #endregion #endregion // ---------------------------------- #region Temp Player setup if (playerNode == null) { playerNode = GameObject.Find ("TempPlayerNode"); if (playerNode == null) { playerNode = new GameObject ("TempPlayerNode"); playerNode.hideFlags = HideFlags.HideAndDontSave; } } if (playerPrefab != null) { foreach (KeyValuePair<Path, bool> p in toggleStatus) { if (p.Value) { if (!players.ContainsKey (p.Key)) { GameObject player = GameObject.Instantiate (playerPrefab) as GameObject; player.transform.position.Set (p.Key.points [0].x, 0f, p.Key.points [0].y); player.transform.parent = playerNode.transform; players.Add (p.Key, player); Material m = new Material (player.renderer.sharedMaterial); m.color = p.Key.color; player.renderer.material = m; player.hideFlags = HideFlags.HideAndDontSave; } else { players [p.Key].SetActive (true); } } else { if (players.ContainsKey (p.Key)) { players [p.Key].SetActive (false); } } } } #endregion EditorGUILayout.EndScrollView (); // ---------------------------------- if (drawer != null) { drawer.timeSlice = timeSlice; drawer.drawHeatMap = drawHeatMap; drawer.drawMap = drawMap; drawer.drawFoVOnly = drawFoVOnly; drawer.drawNeverSeen = drawNeverSeen; drawer.drawPath = drawPath; drawer.drawCombatLines = drawCombatLines; drawer.paths = toggleStatus; drawer.textDraw = textDraw; } if (original != null && lastTime != timeSlice) { lastTime = timeSlice; UpdatePositions (timeSlice, mapper); } SceneView.RepaintAll (); }
public void OnSceneGUI() { // Update drawer if (drawer != null) drawer.editGrid = editGrid; // Stop if needed if (!editGrid) { didUpdate = false; return; } // Create grid if (grid == null || grid.Length != MapperWindowEditor.gridSize) { grid = new Cell[MapperWindowEditor.gridSize][]; for (int i = 0; i < MapperWindowEditor.gridSize; i++) grid [i] = new Cell[MapperWindowEditor.gridSize]; } // Prepare holders if (mapper == null) { mapper = (Mapper)target; } if (drawer == null) { drawer = mapper.gameObject.GetComponent<MapperEditorDrawer> (); } drawer.editingGrid = grid; // Update Scene if (!didUpdate) { mapper.ComputeTileSize (SpaceState.Editor, mapper.collider.bounds.min, mapper.collider.bounds.max, MapperWindowEditor.gridSize, MapperWindowEditor.gridSize); drawer.tileSize.Set (SpaceState.Editor.tileSize.x, SpaceState.Editor.tileSize.y); drawer.zero.Set (SpaceState.Editor.floorMin.x, SpaceState.Editor.floorMin.z); didUpdate = true; } // Raycast Event current = Event.current; if (current != null && EventType.KeyDown == current.type) { Ray ray = HandleUtility.GUIPointToWorldRay (current.mousePosition); RaycastHit hit; if (Physics.Raycast (ray, out hit, Mathf.Infinity, 1 << LayerMask.NameToLayer ("Floor"))) { if (hit.transform.CompareTag ("Floor")) { Vector2 pos = new Vector2 ((hit.point.x - hit.collider.bounds.min.x) / SpaceState.Editor.tileSize.x, (hit.point.z - hit.collider.bounds.min.x) / SpaceState.Editor.tileSize.y); Cell c = grid [(int)pos.x] [(int)pos.y]; if (c == null) { c = new Cell (); grid [(int)pos.x] [(int)pos.y] = c; } switch (current.keyCode) { case KeyCode.Alpha0: grid [(int)pos.x] [(int)pos.y] = null; break; case KeyCode.Alpha1: c.safe = true; break; case KeyCode.Alpha2: c.blocked = true; break; case KeyCode.Alpha3: c.noisy = true; break; case KeyCode.Alpha4: c.waypoint = true; break; case KeyCode.U: c.cluster = 0; break; case KeyCode.Alpha6: c.cluster |= 1; break; case KeyCode.Alpha7: c.cluster |= 2; break; case KeyCode.Alpha8: c.cluster |= 4; break; case KeyCode.Alpha9: c.cluster |= 8; break; case KeyCode.Keypad4: c.cluster |= 8; break; case KeyCode.Keypad5: c.cluster |= 16; break; case KeyCode.Keypad6: c.cluster |= 32; break; case KeyCode.Keypad7: c.cluster |= 64; break; case KeyCode.Keypad8: c.cluster |= 128; break; case KeyCode.Keypad9: c.cluster |= 256; break; } SceneView.RepaintAll (); } } } }