public override void OnInspectorGUI() { if (_target == null) _target = target as WorldGraph; DrawDefaultInspector(); using (gui.Horizontal()) { if (gui.EzButton(gui.LoadValuesButton)) _target.Rot.StartRotation = _target.CameraPivot.rotation.eulerAngles; _target.Rot.StartRotation = gui.EzV3Field ("Rot In", _target.Rot.StartRotation,10f, GUILayout.Width(180f)); } using (gui.Horizontal()) { if (gui.EzButton(gui.LoadValuesButton)) _target.Rot.EndRotation = _target.CameraPivot.rotation.eulerAngles; _target.Rot.EndRotation = gui.EzV3Field("Rot Out", _target.Rot.EndRotation, 10f, GUILayout.Width(180f)); } using (gui.Horizontal()) { _target.Rot.Duration = gui.EzFloatField ("Duration", _target.Rot.Duration, 10f); _target.Rot.EaseType = (Ease)gui.EzEnumPopup ("Ease", _target.Rot.EaseType, 10f); } using (gui.Horizontal()) { if (gui.EzButton ("Import XML Data", GUILayout.Height (24f))) { _target.ImportXML (_idx); } _idx = Mathf.Clamp ((gui.EzIntField ("Idx", _idx, 10f, GUILayout.Width (60f))), 1, 4); } EditorUtility.SetDirty (target); }
public static AssetMoveResult OnWillMoveAsset(string fromPath, string toPath) { //check if we are moving a procedural worlds directory if (Directory.Exists(fromPath)) { string folderName = Path.GetFileName(fromPath); string assetPath = fromPath + "/" + folderName + ".asset"; if (!File.Exists(assetPath)) { return(AssetMoveResult.DidNotMove); } WorldGraph worldGraph = AssetDatabase.LoadMainAssetAtPath(assetPath) as WorldGraph; if (worldGraph == null) { return(AssetMoveResult.DidNotMove); } string toFolderName = Path.GetFileName(toPath); string newAssetPath = toPath + "/" + toFolderName + ".asset"; if (String.IsNullOrEmpty(GraphFactory.GetWorldGraphCreateLocation(toPath))) { Debug.LogError("Can't move the Procedural world directory to " + newAssetPath + ": Not a Resources directory"); return(AssetMoveResult.FailedMove); } Debug.Log("Moving main asset from " + assetPath + " to " + newAssetPath); AssetDatabase.MoveAsset(assetPath, newAssetPath); } return(AssetMoveResult.DidNotMove); }
static PerformanceResult RunTestForGraph(WorldGraph graph) { var result = new PerformanceResult(); Stopwatch sw = new Stopwatch(); result.name = graph.name; sw.Start(); graph.ProcessOnce(); sw.Stop(); result.processOnceTime = sw.Elapsed.TotalMilliseconds; sw.Reset(); sw.Start(); graph.Process(); sw.Stop(); result.processTime = sw.Elapsed.TotalMilliseconds; result.nodeProcessTime = new NodeProcessTime[graph.allNodes.Count()]; for (int i = 0; i < result.nodeProcessTime.Length; i++) { var node = graph.allNodes.ElementAt(i); result.nodeProcessTime[i] = new NodeProcessTime(node.name, node.processTime); } result.totalAllocatedMemory = Profiler.GetTotalAllocatedMemoryLong(); result.totalReservedMemory = Profiler.GetTotalReservedMemoryLong(); result.totalUnusedReservedMemory = Profiler.GetTotalUnusedReservedMemoryLong(); return(result); }
public void ReloadChunks(WorldGraph graphAsset) { InitGraph(graphAsset); DestroyAllChunks(); UpdateChunks(true); }
public static void SimpleSwitchGraphBuild() { WorldGraph graph = TestUtils.GenerateTestWorldGraphBiomeSwitch(); BiomeData bd = new BiomeData(); var wlevel = graph.FindNodeByName("wlevel"); var bswitch = graph.FindNodeByName <NodeBiomeSwitch>("bswitch"); var b1 = graph.FindNodeByName <NodeBiome>("b1"); var b2 = graph.FindNodeByName <NodeBiome>("b2"); bd.biomeSwitchGraphStartPoint = wlevel; PartialBiome p1 = new PartialBiome(); PartialBiome p2 = new PartialBiome(); b1.outputBiome = p1; b2.outputBiome = p2; //setup the switch values var sd = bswitch.switchList.switchDatas; sd[0].min = 0; sd[0].max = 5; sd[0].name = "1"; sd[0].samplerName = BiomeSamplerName.terrainHeight; sd[1].min = 5; sd[1].max = 10; sd[1].name = "2"; sd[1].samplerName = BiomeSamplerName.terrainHeight; Sampler2D terrainHeight = new Sampler2D(32, 1); terrainHeight.min = 0; terrainHeight.max = 10; bd.UpdateSamplerValue(BiomeSamplerName.terrainHeight, terrainHeight); BiomeSwitchGraph switchGraph = new BiomeSwitchGraph(); switchGraph.BuildGraph(bd); Assert.That(switchGraph.isBuilt == true); var values = new BiomeSwitchValues(); values[0] = 4.0f; Assert.That(switchGraph.FindBiome(values).id == p1.id); values[0] = 0f; Assert.That(switchGraph.FindBiome(values).id == p1.id); values[0] = 5f; Assert.That(switchGraph.FindBiome(values).id == p1.id); values[0] = 6.0f; Assert.That(switchGraph.FindBiome(values).id == p2.id); values[0] = 10f; Assert.That(switchGraph.FindBiome(values).id == p2.id); }
public override void OnEnable() { worldGraph = target as WorldGraph; var terrain = TerrainPreviewManager.instance.terrainBase; if (terrain != null) { ReloadChunks(terrain); } }
public static void Run() { string[] performanceGraphGUIDs = AssetDatabase.FindAssets("performance* t:WorldGraph"); //empty log file: File.WriteAllText(logFilePath, string.Empty); logFile = new StreamWriter(File.OpenWrite(logFilePath)); var resultsList = new List <PerformanceResultMulti>(); ProfilerDriver.ClearAllFrames(); ProfilerDriver.deepProfiling = true; Profiler.logFile = tmpProfilerLogFile; Profiler.enabled = true; foreach (var performanceGraphGUID in performanceGraphGUIDs) { string path = AssetDatabase.GUIDToAssetPath(performanceGraphGUID); WorldGraph graph = AssetDatabase.LoadAssetAtPath(path, typeof(WorldGraph)) as WorldGraph; var results = new PerformanceResultMulti(testIterationCount); for (int i = 0; i < testIterationCount; i++) { results.results[i] = RunTestForGraph(graph); } resultsList.Add(results); } Profiler.enabled = false; ProfilerDriver.deepProfiling = false; //this is totally broken in 2017.3 ... #if !UNITY_2017_3 ProfilerDriver.LoadProfile(tmpProfilerLogFile, false); ProfilerDriver.SaveProfile(profilerDataFile); #endif string text = SerializeResults(resultsList); string reportPerfs = Environment.GetEnvironmentVariable("PW_REPORT_PERFORMANCES"); if (reportPerfs == "ON") { ReportPerformaces(resultsList); } logFile.Write(text); logFile.Flush(); }
public Graph mapQuantization(bool isBombPassable, bool isDestructiblePassable) { WorldGraph graph = new WorldGraph (gs.Width * gs.Height); LocationData[,] map = this.gs.Map; for (int i = 0; i < gs.Width; i++) { for (int j = 0; j < gs.Height; j++) { Coords coords = Coords.coordsXY(i, j, gs.Width, gs.Height); int tileNum = coords.getTileNum (); List<Connection> connections = getLegalConnections (map, tileNum, isBombPassable, isDestructiblePassable); graph.addConnections (tileNum, connections); } } return graph; }
/// <summary> /// Calls next array of Locations to destroy /// </summary> public void UpdateDestroyedLocations() { if (llVertex[DestructionOfLocationsIterator] == null) { throw new Exception("Null llVertex array!"); } foreach (Vertex vertex in llVertex[0]) { WorldGraph.RemoveVertex(vertex); } llVertex[DestructionOfLocationsIterator] = null; DestructionOfLocationsIterator++; }
public static void NodeAPIGetNodesAttachedToAnchor() { WorldGraph graph = TestUtils.GenerateTestWorldGraph(); var add4Node = graph.FindNodeByName("add4"); var add1Node = graph.FindNodeByName("add1"); var debug1Node = graph.FindNodeByName("debug1"); var add4NodeInAnchor = add4Node.inputAnchors.First(); var add4NodeOutAnchor = add4Node.outputAnchors.First(); List <BaseNode> add4InputNodes = add4Node.GetNodesAttachedToAnchor(add4NodeInAnchor).ToList(); List <BaseNode> add4OutputNodes = add4Node.GetNodesAttachedToAnchor(add4NodeOutAnchor).ToList(); Assert.That(add4InputNodes[0] == add1Node, "add4 input node was " + add4InputNodes[0] + ", " + add1Node + " expected"); Assert.That(add4OutputNodes[0] == debug1Node, "add4 output node was " + add4OutputNodes[0] + ", " + debug1Node + " expected"); }
void SetupWorld(int width, int height) { this.Width = width; this.Height = height; rooms = new List <Room> (); characters = new List <Character>(); Jobs = new JobQueue(this); storageContainers = new StorageContainers(); tiles = new Tile[width, height]; // Initialise the world array for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { // By default all tiles are empty tiles [x, y] = new Tile(x, y, TileType.Empty, this); tiles [x, y].OnBorderDefinitionChanged += OnTileBorderDefinitionChanged; tiles [x, y].OnTileAdditionChanged += OnTileAdditionChanged; } } // Every world starts with a default 10x10 room in the middle int s = 5; for (int x = -s; x <= s; x++) { for (int y = -s; y <= s; y++) { Tile t = tiles [width / 2 + x, height / 2 + y]; t.SetFloor(); if (x == s || x == -s || y == s || y == -s) { t.InstallAddition(new Wall(t), true); } } } Room startRoom = new Room(this, tiles [width / 2, height / 2]); AddRoom(startRoom); graph = new WorldGraph(rooms, this); }
void InitGraph(WorldGraph graphAsset) { this.graphAsset = graphAsset; this.graph = graphAsset.Clone() as WorldGraph; graph.SetRealMode(true); chunkSize = graph.chunkSize; if (terrainRoot == null) { UpdateTerrainRoot(); } graph.UpdateComputeOrder(); graph.ProcessOnce(); UpdateChunks(true); }
public static void NodeAPIGetNodesAttachedToAnchorArray() { WorldGraph graph = TestUtils.GenerateTestWorldGraph(); var add2Node = graph.FindNodeByName("add2"); var sliderNode = graph.FindNodeByName("slider"); var debug2Node = graph.FindNodeByName("debug2"); var add2NodeInputAnchor = add2Node.inputAnchors.First(); var add2NodeOutputAnchor = add2Node.outputAnchors.First(); List <BaseNode> inputNodes = add2Node.GetNodesAttachedToAnchor(add2NodeInputAnchor).ToList(); List <BaseNode> outputNodes = add2Node.GetNodesAttachedToAnchor(add2NodeOutputAnchor).ToList(); Assert.That(inputNodes.Count == 1); Assert.That(inputNodes[0] == sliderNode); Assert.That(outputNodes.Count == 1); Assert.That(outputNodes[0] == debug2Node); }
public static void GetNodeChildsRecursiveTest() { WorldGraph worldGraph = TestUtils.GenerateTestWorldGraphBiomeSwitch(); var wlevel = worldGraph.FindNodeByName("wlevel"); var recursiveNodesFromC2 = worldGraph.GetNodeChildsRecursive(wlevel); //check for duplicates Assert.That(recursiveNodesFromC2.Count == recursiveNodesFromC2.Distinct().Count()); //check for compute order: for (int i = 0; i < recursiveNodesFromC2.Count - 1; i++) { var node1 = recursiveNodesFromC2[i]; var node2 = recursiveNodesFromC2[i + 1]; Assert.That(node1.computeOrder <= node2.computeOrder, "Nodes from GetNodeChildsRecursive are not computeOrder sorted"); } }
public static void CloneWorldGraphTest() { WorldGraph worldGraph = TestUtils.GenerateTestWorldGraph(); WorldGraph clonedGraph = worldGraph.Clone() as WorldGraph; Assert.That(worldGraph.nodes.Count == clonedGraph.nodes.Count); Assert.That(worldGraph.allNodes.Count() == clonedGraph.allNodes.Count()); Assert.That(worldGraph.nodeLinkTable.GetLinks().Count() == clonedGraph.nodeLinkTable.GetLinks().Count()); foreach (var node in clonedGraph.allNodes) { Assert.That(worldGraph.allNodes.Contains(node) == false); } foreach (var node in clonedGraph.allNodes) { foreach (var anchorField in node.anchorFields) { foreach (var anchor in anchorField.anchors) { foreach (var link in anchor.links) { Assert.That(link.toNode != null); Assert.That(link.fromNode != null); Assert.That(clonedGraph.FindNodeById(link.toNode.id) != null); Assert.That(clonedGraph.FindNodeById(link.fromNode.id) != null); Assert.That(worldGraph.allNodes.Contains(link.fromNode) == false); Assert.That(worldGraph.allNodes.Contains(link.toNode) == false); } } } } Assert.That(clonedGraph.readyToProcess == true); clonedGraph.Process(); }
public override void OnInspectorGUI() { if (_target == null) { _target = target as WorldGraph; } DrawDefaultInspector(); using (gui.Horizontal()) { if (gui.EzButton(gui.LoadValuesButton)) { _target.Rot.StartRotation = _target.CameraPivot.rotation.eulerAngles; } _target.Rot.StartRotation = gui.EzV3Field("Rot In", _target.Rot.StartRotation, 10f, GUILayout.Width(180f)); } using (gui.Horizontal()) { if (gui.EzButton(gui.LoadValuesButton)) { _target.Rot.EndRotation = _target.CameraPivot.rotation.eulerAngles; } _target.Rot.EndRotation = gui.EzV3Field("Rot Out", _target.Rot.EndRotation, 10f, GUILayout.Width(180f)); } using (gui.Horizontal()) { _target.Rot.Duration = gui.EzFloatField("Duration", _target.Rot.Duration, 10f); _target.Rot.EaseType = (Ease)gui.EzEnumPopup("Ease", _target.Rot.EaseType, 10f); } using (gui.Horizontal()) { if (gui.EzButton("Import XML Data", GUILayout.Height(24f))) { _target.ImportXML(_idx); } _idx = Mathf.Clamp((gui.EzIntField("Idx", _idx, 10f, GUILayout.Width(60f))), 1, 4); } EditorUtility.SetDirty(target); }
void OnDrawGizmos() { if (!EditorApplication.isPlaying || world.GetCharacters() == null || world.GetCharacters().Count == 0) { return; } // Draw the graph for every room Gizmos.color = Color.black; WorldGraph graph = world.Graph; foreach (Node <Tile> node in graph.nodes.Values) { foreach (Edge <Tile> edge in node.edges) { Gizmos.DrawLine( new Vector3(node.data.X, node.data.Y, 0), new Vector3(edge.destination.data.X, edge.destination.data.Y, 0)); } } // Draw the graph to indicate which rooms connect to which rooms // Display a gizmo for the room pathfinding graph Gizmos.color = Color.green; WorldGraph worldGraph = world.Graph; foreach (Node <Tile> node in worldGraph.nodes.Values) { foreach (Edge <Tile> edge in node.edges) { Gizmos.DrawLine( new Vector3(node.data.X, node.data.Y, 0), new Vector3(edge.destination.data.X, edge.destination.data.Y, 0)); } } }
public AStar(WorldGraph graph, Tile tileStart, Tile tileEnd) { // A dictionary of all valid walkable nodes Dictionary <Tile, Node <Tile> > nodes = graph.nodes; // Make sure start/end tiles are in the list of nodes if (nodes.ContainsKey(tileStart) == false) { Debug.LogError("AStar: the starting tile isn't in the list of nodes"); return; } if (nodes.ContainsKey(tileEnd) == false) { Debug.LogError("AStar: the end tile isn't in the list of nodes"); return; } Node <Tile> start = nodes [tileStart]; Node <Tile> goal = nodes [tileEnd]; /* * Mostly following this pseudocode: * https://en.wikipedia.org/wiki/A*_search_algorithm */ List <Node <Tile> > closedSet = new List <Node <Tile> > (); SimplePriorityQueue <Node <Tile> > openSet = new SimplePriorityQueue <Node <Tile> > (); openSet.Enqueue(start, 0); Dictionary <Node <Tile>, Node <Tile> > came_from = new Dictionary <Node <Tile>, Node <Tile> > (); Dictionary <Node <Tile>, float> g_score = new Dictionary <Node <Tile>, float> (); foreach (Node <Tile> n in nodes.Values) { g_score [n] = Mathf.Infinity; } g_score [start] = 0; Dictionary <Node <Tile>, float> f_score = new Dictionary <Node <Tile>, float> (); foreach (Node <Tile> n in nodes.Values) { f_score [n] = Mathf.Infinity; } f_score [start] = Heuristic_cost_estimate(start, goal); while (openSet.Count > 0) { Node <Tile> current = openSet.Dequeue(); if (current == goal) { // We have reached our goal, lets convert this to an actual sequence of tiles to walk on // then end this constructor function ReconstructPath(came_from, current); //Debug.Log ("Found path of length: " + this.Length ()); return; } closedSet.Add(current); foreach (Edge <Tile> edgeNeigbour in current.edges) { Node <Tile> neighbor = edgeNeigbour.destination; if (closedSet.Contains(neighbor)) { continue; // ignore this already completed neighbor } float movementCostToNeigbour = neighbor.data.MovementCost * DistBetween(current, neighbor); float tentative_g_score = g_score [current] + movementCostToNeigbour; if (openSet.Contains(neighbor) && tentative_g_score >= g_score[neighbor]) { continue; } came_from [neighbor] = current; g_score [neighbor] = tentative_g_score; f_score [neighbor] = g_score [neighbor] + Heuristic_cost_estimate(neighbor, goal); if (openSet.Contains(neighbor) == false) { openSet.Enqueue(neighbor, f_score [neighbor]); } else { openSet.UpdatePriority(neighbor, f_score [neighbor]); } } // foreach neigbour } // while Debug.LogError("No path found to destination"); // If we reached here, it means we've burned through the entire // OpenSet without ever re aching a point where current == goal // This happens when there is no path from start to goal // (so there's a wall or missing floor or something) // We don't have a failure state, maybe? It's just that th // pathlist will be null }
public AStarWorldPath(WorldGraph graph, Tile tileStart, Tile tileEnd) { // A dictionary of all valid walkable nodes (doors in this case) Dictionary <Tile, Node <Tile> > nodes = graph.nodes; // Make sure start/end tiles rooms have a door bool containsStart = false; if (tileStart.Room == null || tileEnd.Room == null) { Debug.LogError("Trying to move on top of a door"); } if (!tileStart.Room.additions.ContainsKey(Door.AdditionName)) { Debug.LogError("Starting room does not have a door to leave the room"); return; } if (!tileEnd.Room.additions.ContainsKey(Door.AdditionName)) { Debug.LogError("Destination room does not have a door to enter the room"); return; } // Make sure we are aware of the door foreach (TileAddition door in tileStart.Room.additions[Door.AdditionName]) { if (nodes.ContainsKey(door.tile)) { containsStart = true; break; } } if (containsStart == false) { Debug.LogError("AStarWorld: the starting door isn't in the list of nodes"); return; } bool containsEnd = false; foreach (TileAddition door in tileEnd.Room.additions[Door.AdditionName]) { if (nodes.ContainsKey(door.tile)) { containsEnd = true; break; } } if (containsEnd == false) { Debug.LogError("AStarWorld: the end door isn't in the list of nodes"); return; } /// // START OF ACTUAL PATHFINDING /// /* * Mostly following this pseudocode: * https://en.wikipedia.org/wiki/A*_search_algorithm */ List <Node <Tile> > closedSet = new List <Node <Tile> > (); SimplePriorityQueue <Node <Tile> > openSet = new SimplePriorityQueue <Node <Tile> > (); Dictionary <Node <Tile>, Node <Tile> > came_from = new Dictionary <Node <Tile>, Node <Tile> > (); Dictionary <Node <Tile>, float> g_score = new Dictionary <Node <Tile>, float> (); foreach (Node <Tile> n in nodes.Values) { g_score [n] = Mathf.Infinity; } Dictionary <Node <Tile>, float> f_score = new Dictionary <Node <Tile>, float> (); foreach (Node <Tile> n in nodes.Values) { f_score [n] = Mathf.Infinity; } // enqueue all doors from the starting room Node <Tile> charNode = new Node <Tile>(); charNode.data = tileStart; Node <Tile> destNode = new Node <Tile>(); destNode.data = tileEnd; foreach (TileAddition door in tileStart.Room.additions[Door.AdditionName]) { // enqueue them based on their distance from the character (straight line heuristic, lets assume no shenanigans) Node <Tile> curNode = nodes [door.tile]; openSet.Enqueue(curNode, Heuristic_cost_estimate(charNode, curNode)); g_score [curNode] = Heuristic_cost_estimate(charNode, curNode); f_score [curNode] = Heuristic_cost_estimate(curNode, destNode); } while (openSet.Count > 0) { Node <Tile> current = openSet.Dequeue(); // We reached our goal if our current node is part of the doors of the destination room foreach (TileAddition door in tileEnd.Room.additions[Door.AdditionName]) { if (current.data == door.tile) { // We have reached our goal, lets convert this to an actual sequence of tiles to walk on // then end this constructor function Debug.Log("Found a path in our world graph"); ReconstructPath(came_from, current); return; } } closedSet.Add(current); foreach (Edge <Tile> edgeNeigbour in current.edges) { Node <Tile> neighbor = edgeNeigbour.destination; if (closedSet.Contains(neighbor)) { continue; // ignore this already completed neighbor } float movementCostToNeigbour = neighbor.data.MovementCost * Heuristic_cost_estimate(current, neighbor); float tentative_g_score = g_score [current] + movementCostToNeigbour; if (openSet.Contains(neighbor) && tentative_g_score >= g_score[neighbor]) { continue; } came_from [neighbor] = current; g_score [neighbor] = tentative_g_score; f_score [neighbor] = g_score [neighbor] + Heuristic_cost_estimate(neighbor, destNode); if (openSet.Contains(neighbor) == false) { openSet.Enqueue(neighbor, f_score [neighbor]); } else { openSet.UpdatePriority(neighbor, f_score [neighbor]); } } // foreach neigbour } // while // If we reached here, it means we've burned through the entire // OpenSet without ever re aching a point where current == goal // This happens when there is no path from start to goal // (so there's a wall or missing floor or something) // We don't have a failure state, maybe? It's just that th // pathlist will be null }
public static void Load() { MapDictionary = LoadMaps(); world = new WorldGraph(); }