void OnDestroy() { if (instance == this) { instance = null; } }
void Awake() { if (instance) { // enforce singleton Destroy(this); return; } else { instance = this; manualSeed = Mathf.Max(0, manualSeed); // make sure area size is valid int numCells = Mathf.FloorToInt(areaSize / cellSize); _areaSize = numCells * cellSize; // populate cell array cells = new Cell[numCells, numCells]; for (int x = 0; x < numCells; x++) { for (int y = 0; y < numCells; y++) { Cell newCell = new Cell(x, y); // close cells on borders if (x == 0) { newCell.canGoWest = false; } if (x == numCells - 1) { newCell.canGoEast = false; } if (y == 0) { newCell.canGoSouth = false; } if (y == numCells - 1) { newCell.canGoNorth = false; } cells[x, y] = newCell; } } } }
public Cell CellInDirection(Direction dir) { switch (dir) { case Direction.North: if (y < CellGen.cellsPerSide - 1) { return(CellGen.GetCellAt(x, y + 1)); } break; case Direction.South: if (y > 0) { return(CellGen.GetCellAt(x, y - 1)); } break; case Direction.East: if (x < CellGen.cellsPerSide - 1) { return(CellGen.GetCellAt(x + 1, y)); } break; case Direction.West: if (x > 0) { return(CellGen.GetCellAt(x - 1, y)); } break; default: Debug.LogWarning("Invalid direction " + dir); break; } return(null); }
void Awake() { if ( instance ) { // enforce singleton Destroy( this ); return; } else { instance = this; manualSeed = Mathf.Max ( 0, manualSeed ); // make sure area size is valid int numCells = Mathf.FloorToInt( areaSize / cellSize ); _areaSize = numCells * cellSize; // populate cell array cells = new Cell[ numCells, numCells ]; for ( int x = 0; x < numCells; x++ ) for ( int y = 0; y < numCells; y++ ) { Cell newCell = new Cell( x, y ); // close cells on borders if ( x == 0 ) newCell.canGoWest = false; if ( x == numCells - 1) newCell.canGoEast = false; if ( y == 0 ) newCell.canGoSouth = false; if ( y == numCells - 1 ) newCell.canGoNorth = false; cells[x,y] = newCell; } } }
public override void OnInspectorGUI() { serializedObject.Update(); if (blackTexture == null) { blackTexture = new Texture2D(2, 2); blackTexture.SetPixels32(new Color32[] { new Color32(0, 0, 0, 255), new Color32(0, 0, 0, 255), new Color32(0, 0, 0, 255), new Color32(0, 0, 0, 255) }); blackTexture.Apply(); } CellGen cellGen = target as CellGen; if (GUILayout.Button("Generate")) { cellGen.Generate(); } EditorGUILayout.PropertyField(previewGizmoProp); EditorGUILayout.PropertyField(randomizeProp); if (!randomizeProp.boolValue) { EditorGUILayout.PropertyField(seedProp); } EditorGUILayout.PropertyField(widthProp); EditorGUILayout.PropertyField(heightProp); EditorGUILayout.PropertyField(densityProp); for (int i = 0; i < genMethods.arraySize; i++) { GUILayout.BeginHorizontal(); int currentIndex = System.Array.IndexOf(CellGen.methodNames, genMethods.GetArrayElementAtIndex(i).stringValue); int newIndex = EditorGUILayout.Popup(currentIndex, CellGen.methodNames); if (newIndex != currentIndex) { genMethods.GetArrayElementAtIndex(i).stringValue = CellGen.methodNames[newIndex]; } if (GUILayout.Button(new GUIContent("+", "Duplicate"), GUILayout.Width(20))) { genMethods.InsertArrayElementAtIndex(i); genMethods.GetArrayElementAtIndex(i).stringValue = genMethods.GetArrayElementAtIndex(i + 1).stringValue; } if (i != 0) { if (GUILayout.Button(new GUIContent("⇑", "move up"), GUILayout.Width(20))) { genMethods.MoveArrayElement(i, i - 1); } } else { GUILayout.Space(23f); } if (i != genMethods.arraySize - 1) { if (GUILayout.Button(new GUIContent("⇓", "move down"), GUILayout.Width(20))) { genMethods.MoveArrayElement(i, i + 1); } } else { GUILayout.Space(23f); } if (GUILayout.Button(new GUIContent("☓", "delete"), GUILayout.Width(20))) { genMethods.DeleteArrayElementAtIndex(i); } GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button(new GUIContent("+", "add new method"))) { genMethods.InsertArrayElementAtIndex(genMethods.arraySize); genMethods.GetArrayElementAtIndex(genMethods.arraySize - 1).stringValue = CellGen.methodNames[0]; } GUILayout.EndHorizontal(); if (cellGen.tiles != null) { int width = cellGen.tiles.GetLength(0); int height = cellGen.tiles.GetLength(1); var rect = GUILayoutUtility.GetAspectRect((float)width / height); float tileSize = rect.width / width; Vector2 start = new Vector2(rect.x, rect.y); GUI.DrawTexture(rect, cellGen.outputTexture); } GUILayout.Label($"Generation time: {cellGen.genTime.ToString("0.00")}ms"); serializedObject.ApplyModifiedProperties(); }
public static Vector3[] PathTo(Vector3 fromPoint, Vector3 toPoint) { fromPoint.y = toPoint.y = 0; Cell startCell = CellGen.GetCellAt(fromPoint); Cell endCell = CellGen.GetCellAt(toPoint); if (startCell.x < 0 || endCell.y < 0) { Debug.Log("Invalid path start and/or end"); return(null); } // A* setup var evaluated = new List <Cell>(); var toEvaluate = new List <Cell>(); var cameFrom = new Dictionary <Cell, Cell>(); var costTo = new Dictionary <Cell, int>(); var costFrom = new Dictionary <Cell, float>(); var totalCost = new Dictionary <Cell, float>(); toEvaluate.Add(startCell); costTo.Add(startCell, 0); costFrom.Add(startCell, HeuristicDist(startCell, endCell)); totalCost.Add(startCell, costFrom[startCell]); // A* loop while (toEvaluate.Count > 0) { Cell evalPoint = null; float lowestCost = float.MaxValue; foreach (var cell in toEvaluate) // perhaps ove toeval to a heap or something { float newCost = totalCost[cell]; if (newCost < lowestCost) { lowestCost = newCost; evalPoint = cell; } } // if reached dest if (evalPoint == endCell) { var cellPath = PathFrom(cameFrom, evalPoint); var path = new List <Vector3>(); path.Add(fromPoint); for (int i = 1; i < cellPath.Count - 1; i++) { path.Add(cellPath[i].centrePosition); } path.Add(toPoint); path = SmoothPath(path); return(path.ToArray()); } toEvaluate.Remove(evalPoint); evaluated.Add(evalPoint); var neighbours = new List <Cell>(); if (evalPoint.canGoNorth && evalPoint.CellInDirection(Direction.North).room != 0) { neighbours.Add(evalPoint.CellInDirection(Direction.North)); } if (evalPoint.canGoSouth && evalPoint.CellInDirection(Direction.South).room != 0) { neighbours.Add(evalPoint.CellInDirection(Direction.South)); } if (evalPoint.canGoEast && evalPoint.CellInDirection(Direction.East).room != 0) { neighbours.Add(evalPoint.CellInDirection(Direction.East)); } if (evalPoint.canGoWest && evalPoint.CellInDirection(Direction.West).room != 0) { neighbours.Add(evalPoint.CellInDirection(Direction.West)); } foreach (Cell newPoint in neighbours) { if (evaluated.Contains(newPoint)) { continue; } int tentCostTo = costTo[evalPoint] + 1; if (!toEvaluate.Contains(newPoint)) { toEvaluate.Add(newPoint); costTo.Add(newPoint, tentCostTo); costFrom.Add(newPoint, HeuristicDist(newPoint, endCell)); totalCost.Add(newPoint, tentCostTo + costFrom[newPoint]); cameFrom.Add(newPoint, evalPoint); } else if (tentCostTo < costTo[newPoint]) { costTo[newPoint] = tentCostTo; cameFrom[newPoint] = evalPoint; totalCost[newPoint] = tentCostTo + costFrom[newPoint]; } } } Debug.Log("No path found from " + fromPoint + " to " + toPoint); return(null); }
void OnDestroy() { if ( instance == this ) instance = null; }