private void PathGFX() { if (pathPositions.Count == 1) { GameObject targetGameObj = GameObject.Find("Target"); if (targetGameObj != null) { LineRenderer lr = pathRenderGFX.GetComponent <LineRenderer>(); lr.SetWidth(0.25f, 0.25f); Vector3 startPosition = pathPositions[0]; Assets.Map.Center startTileCenter = Graph.centers.FirstOrDefault(p => p.PointInside(startPosition.x, startPosition.z)); if (startTileCenter != null) { startPosition.y = startTileCenter.elevation + 0.5f; Vector3 endPosition = targetGameObj.transform.position; Assets.Map.Center endTileCenter = Graph.centers.FirstOrDefault(p => p.PointInside(endPosition.x, endPosition.z)); if (endTileCenter != null) { endPosition.y = endTileCenter.elevation + 0.5f; lr.SetPosition(0, startPosition); lr.SetPosition(1, endPosition); } } } } }
private void DrawNoisyPolygon(Texture2D texture, Center p, List<Vector2> orgEdges) { _edgePoints.Clear(); _edgePoints.AddRange(orgEdges); _edgePoints.Add(p.point); texture.FillPolygon( _edgePoints.Select(x => new Vector2(x.x * _textureScale, x.y * _textureScale)).ToArray(), BiomeProperties.Colors[p.biome]); }
public void AddTerrainPath(Vector3 pathPoint, string pathType, int brushHeight) { //Place path if (pathPositions.Count == 1) { pathPositions.Add(pathPoint); Assets.Map.Center startTileCenter = Graph.centers.FirstOrDefault(p => p.PointInside(pathPositions [0].x, pathPositions [0].z)); Assets.Map.Center endTileCenter = Graph.centers.FirstOrDefault(p => p.PointInside(pathPositions [1].x, pathPositions [1].z)); if (startTileCenter != endTileCenter) { Vector3 path = pathPositions [1] - pathPositions [0]; Assets.Map.Center tileCenter = startTileCenter; for (Vector3 pathSegment = Vector3.zero; Vector3.Magnitude(pathSegment) <= Vector3.Magnitude(path); pathSegment += path / 50) { Vector3 segment = pathPositions [0] + pathSegment; Assets.Map.Center thisTileCenter = Graph.centers.FirstOrDefault(p => p.PointInside(segment.x, segment.z)); if (thisTileCenter != null && tileCenter != null) { if (thisTileCenter != tileCenter) { switch (pathType) { case MapGenMenu.SubTitle_Ramps: if (thisTileCenter.elevation < tileCenter.elevation) { AddRamp(tileCenter, thisTileCenter); } else { AddRamp(thisTileCenter, tileCenter); } break; case MapGenMenu.SubTitle_Tiles: PlaceTile(tileCenter.point.x, tileCenter.point.y, brushHeight); break; } tileCenter = thisTileCenter; } } } } pathPositions.Clear(); Object.Destroy(pathRenderGFX); } }
public void PlaceTile(float x, float y, int brushHeight) { Assets.Map.Center selectedCenter = Graph.centers.FirstOrDefault(p => p.PointInside(x, y)); if (selectedCenter != null) { selectedCenter.elevation = brushHeight; // rebuild BuildVoronoiTileGFX(selectedCenter); bRescanNavGraph = true; } }
public void AddRoom(Vector3 cornerPoint, int brushHeight) { //Place path if (roomPositions.Count == 1) { roomPositions.Add(cornerPoint); Assets.Map.Center startTileCenter = Graph.centers.FirstOrDefault(p => p.PointInside(roomPositions [0].x, roomPositions [0].z)); Assets.Map.Center endTileCenter = Graph.centers.FirstOrDefault(p => p.PointInside(roomPositions [1].x, roomPositions [1].z)); if (startTileCenter != endTileCenter) { Vector3 path = roomPositions [1] - roomPositions [0]; Assets.Map.Center tileCenter = startTileCenter; foreach (Assets.Map.Center selectedCenter in Graph.centers) { float minX = Mathf.Min(roomPositions[0].x, roomPositions[1].x); float maxX = Mathf.Max(roomPositions[0].x, roomPositions[1].x); if (selectedCenter.point.x > minX && selectedCenter.point.x < maxX) { float minZ = Mathf.Min(roomPositions[0].z, roomPositions[1].z); float maxZ = Mathf.Max(roomPositions[0].z, roomPositions[1].z); if (selectedCenter.point.y > minZ && selectedCenter.point.y < maxZ) { PlaceTile(selectedCenter.point.x, selectedCenter.point.y, brushHeight); } } } } roomPositions.Clear(); Object.Destroy(roomRenderGFX[0]); Object.Destroy(roomRenderGFX[1]); Object.Destroy(roomRenderGFX[2]); Object.Destroy(roomRenderGFX[3]); } }
private void RoomGFX() { if (roomPositions.Count == 1) { GameObject targetGameObj = GameObject.Find("Target"); if (targetGameObj != null) { for (int side = 0; side < 4; side++) { LineRenderer lr = roomRenderGFX[side].GetComponent <LineRenderer>(); lr.SetWidth(0.25f, 0.25f); Vector3 startPosition = new Vector3(0, 0, 0); switch (side) { case 0: startPosition = roomPositions[0]; break; case 1: startPosition = targetGameObj.transform.position; break; case 2: startPosition = roomPositions[0]; startPosition.z = targetGameObj.transform.position.z; break; case 3: startPosition = roomPositions[0]; startPosition.x = targetGameObj.transform.position.x; break; } Assets.Map.Center startTileCenter = Graph.centers.FirstOrDefault(p => p.PointInside(startPosition.x, startPosition.z)); if (startTileCenter != null) { startPosition.y = startTileCenter.elevation + 0.5f; Vector3 endPosition = new Vector3(0, 0, 0); switch (side) { case 0: endPosition = roomPositions[0]; endPosition.x = targetGameObj.transform.position.x; break; case 1: endPosition = roomPositions[0]; endPosition.z = targetGameObj.transform.position.z; break; case 2: endPosition = roomPositions[0]; break; case 3: endPosition = targetGameObj.transform.position; break; } Assets.Map.Center endTileCenter = Graph.centers.FirstOrDefault(p => p.PointInside(endPosition.x, endPosition.z)); if (endTileCenter != null) { endPosition.y = endTileCenter.elevation + 0.5f; lr.SetPosition(0, startPosition); lr.SetPosition(1, endPosition); } } } } } }
internal void Click(Vector2 point) { SelectedCenter = Graph.centers.FirstOrDefault(p => p.PointInside(point.x, point.y)); }
private void BuildGraph(IEnumerable<Vector2> points, Delaunay.Voronoi voronoi) { // Build graph data structure in 'edges', 'centers', 'corners', // based on information in the Voronoi results: point.neighbors // will be a list of neighboring points of the same type (corner // or center); point.edges will be a list of edges that include // that point. Each edge connects to four points: the Voronoi edge // edge.{v0,v1} and its dual Delaunay triangle edge edge.{d0,d1}. // For boundary polygons, the Delaunay edge will have one null // point, and the Voronoi edge may be null. var libedges = voronoi.Edges(); var centerLookup = new Dictionary<Vector2?, Center>(); // Build Center objects for each of the points, and a lookup map // to find those Center objects again as we build the graph foreach (var point in points) { var p = new Center { index = centers.Count, point = point }; centers.Add(p); centerLookup[point] = p; } // Workaround for Voronoi lib bug: we need to call region() // before Edges or neighboringSites are available foreach (var p in centers) { voronoi.Region(p.point); } foreach (var libedge in libedges) { var dedge = libedge.DelaunayLine(); var vedge = libedge.VoronoiEdge(); // Fill the graph data. Make an Edge object corresponding to // the edge from the voronoi library. var edge = new Edge { index = edges.Count, river = 0, // Edges point to corners. Edges point to centers. v0 = MakeCorner(vedge.p0), v1 = MakeCorner(vedge.p1), d0 = centerLookup[dedge.p0], d1 = centerLookup[dedge.p1] }; if (vedge.p0.HasValue && vedge.p1.HasValue) edge.midpoint = Vector2Extensions.Interpolate(vedge.p0.Value, vedge.p1.Value, 0.5f); edges.Add(edge); // Centers point to edges. Corners point to edges. if (edge.d0 != null) { edge.d0.borders.Add(edge); } if (edge.d1 != null) { edge.d1.borders.Add(edge); } if (edge.v0 != null) { edge.v0.protrudes.Add(edge); } if (edge.v1 != null) { edge.v1.protrudes.Add(edge); } // Centers point to centers. if (edge.d0 != null && edge.d1 != null) { AddToCenterList(edge.d0.neighbors, edge.d1); AddToCenterList(edge.d1.neighbors, edge.d0); } // Corners point to corners if (edge.v0 != null && edge.v1 != null) { AddToCornerList(edge.v0.adjacent, edge.v1); AddToCornerList(edge.v1.adjacent, edge.v0); } // Centers point to corners if (edge.d0 != null) { AddToCornerList(edge.d0.corners, edge.v0); AddToCornerList(edge.d0.corners, edge.v1); } if (edge.d1 != null) { AddToCornerList(edge.d1.corners, edge.v0); AddToCornerList(edge.d1.corners, edge.v1); } // Corners point to centers if (edge.v0 != null) { AddToCenterList(edge.v0.touches, edge.d0); AddToCenterList(edge.v0.touches, edge.d1); } if (edge.v1 != null) { AddToCenterList(edge.v1.touches, edge.d0); AddToCenterList(edge.v1.touches, edge.d1); } } // TODO: use edges to determine these var topLeft = centers.OrderBy(p => p.point.x + p.point.y).First(); AddCorner(topLeft, 0, 0); var bottomRight = centers.OrderByDescending(p => p.point.x + p.point.y).First(); AddCorner(bottomRight, Width, Height); var topRight = centers.OrderByDescending(p => Width - p.point.x + p.point.y).First(); AddCorner(topRight, 0, Height); var bottomLeft = centers.OrderByDescending(p => p.point.x + Height - p.point.y).First(); AddCorner(bottomLeft, Width, 0); // required for polygon fill foreach (var center in centers) { center.corners.Sort(ClockwiseComparison(center)); } }
static Biome GetBiome(Center p) { if (p.ocean) { return(Biome.Ocean); } else if (p.water) { if (p.elevation < 0.1) { return(Biome.Marsh); } if (p.elevation > 0.8) { return(Biome.Ice); } return(Biome.Lake); } else if (p.coast) { return(Biome.Beach); } else if (p.elevation > 0.8) { if (p.moisture > 0.50) { return(Biome.Snow); } else if (p.moisture > 0.33) { return(Biome.Tundra); } else if (p.moisture > 0.16) { return(Biome.Bare); } else { return(Biome.Scorched); } } else if (p.elevation > 0.6) { if (p.moisture > 0.66) { return(Biome.Taiga); } else if (p.moisture > 0.33) { return(Biome.Shrubland); } else { return(Biome.TemperateDesert); } } else if (p.elevation > 0.3) { if (p.moisture > 0.83) { return(Biome.TemperateRainForest); } else if (p.moisture > 0.50) { return(Biome.TemperateDeciduousForest); } else if (p.moisture > 0.16) { return(Biome.Grassland); } else { return(Biome.TemperateDesert); } } else { if (p.moisture > 0.66) { return(Biome.TropicalRainForest); } else if (p.moisture > 0.33) { return(Biome.TropicalSeasonalForest); } else if (p.moisture > 0.16) { return(Biome.Grassland); } else { return(Biome.SubtropicalDesert); } } }
// Ramp between selectedCenter and target center (c) public void AddRamp(Assets.Map.Center selectedCenter, Assets.Map.Center c) { if (c.elevation < selectedCenter.elevation) { foreach (Assets.Map.Edge edge in c.borders) { if (edge.d0 == selectedCenter || edge.d1 == selectedCenter) // todo: floating point equaulity may break with non-integer floats. { // this is the edge which connects to the selected site if (edge.gameObjectRamp.Count == 0) { edge.gameObjectWalls.ForEach(_gfx => Object.Destroy(_gfx)); edge.gameObjectWalls.Clear(); edge.gameObjectWallsViz.ForEach(_gfx => Object.Destroy(_gfx)); edge.gameObjectWallsViz.Clear(); edge.gameObjectRamp.ForEach(_gfx => Object.Destroy(_gfx)); edge.gameObjectRamp.Clear(); Vector2 halfEdgeVector = edge.v0.point - edge.v1.point; halfEdgeVector = halfEdgeVector / 2; Vector2 centerVector = c.point - selectedCenter.point; centerVector = centerVector / 2; GameObject obj = Object.Instantiate(assetLibrary.GetComponent <AssetLibrary>().collisionPrefab, new Vector3(c.point.x, 0, c.point.y), Quaternion.identity) as GameObject; obj.layer = 8; //ground obj.name = "rampCollision"; //obj.GetComponent<Renderer>().enabled = false; // hide collison mesh obj.GetComponent <MeshFilter>().mesh.vertices = new Vector3[] { new Vector3(edge.v1.point.x - c.point.x, selectedCenter.elevation, edge.v1.point.y - c.point.y), new Vector3(edge.v1.point.x - c.point.x + centerVector.x, c.elevation, edge.v1.point.y - c.point.y + centerVector.y), new Vector3(edge.v0.point.x - c.point.x, selectedCenter.elevation, edge.v0.point.y - c.point.y), new Vector3(edge.v0.point.x - c.point.x + centerVector.x, c.elevation, edge.v0.point.y - c.point.y + centerVector.y) }; obj.GetComponent <MeshFilter>().mesh.uv = new [] { new Vector2(1, 1), new Vector2(1, 0), new Vector2(0, 1), new Vector2(0, 0) }; // tri ordering is based on vectors between center and adjacent center if (c.point.y == selectedCenter.point.y) //TODO: float equality { if (c.point.x < selectedCenter.point.x) { obj.GetComponent <MeshFilter>().mesh.triangles = new [] { 0, 1, 2, 2, 1, 3 }; } else { obj.GetComponent <MeshFilter>().mesh.triangles = new [] { 0, 2, 1, 1, 2, 3 }; } } else if (c.point.y > selectedCenter.point.y) { obj.GetComponent <MeshFilter>().mesh.triangles = new [] { 0, 2, 1, 1, 2, 3 }; } else if (c.point.y < selectedCenter.point.y) { obj.GetComponent <MeshFilter>().mesh.triangles = new [] { 0, 1, 2, 2, 1, 3 }; } obj.GetComponent <MeshFilter>().mesh.RecalculateNormals(); //obj.AddComponent<MeshCollider>(); obj.GetComponent <MeshCollider>().sharedMesh = obj.GetComponent <MeshFilter>().mesh; obj.transform.SetParent(this.transform); edge.gameObjectRamp.Add(obj); // Ramp Viz Object Vector3 newPos = (new Vector3(edge.v0.point.x, 0, edge.v0.point.y) + new Vector3(edge.v1.point.x, 0, edge.v1.point.y)) / 2; newPos.y = c.elevation; GameObject vizObj = Object.Instantiate(assetLibrary.GetComponent <AssetLibrary>().VizPrefabStair, newPos, Quaternion.identity) as GameObject; vizObj.name = "VizPrefabStair"; // flag MeshFilter game objects as viz layer MeshFilter[] childmf = vizObj.GetComponentsInChildren <MeshFilter>(); int ct = 0; while (ct < childmf.Length) { MeshFilter cmf = childmf[ct]; if (cmf != null) { cmf.gameObject.layer = 10; } ct++; } // rotate to angle of edge face float yAngle = Vector3.Angle(new Vector3(0, 0, 1), new Vector3(c.point.x, 0, c.point.y) - new Vector3(selectedCenter.point.x, 0, selectedCenter.point.y)); if (selectedCenter.point.x > c.point.x) { vizObj.transform.Rotate(0, -yAngle, 0); } else { vizObj.transform.Rotate(0, yAngle, 0); } Vector3 ls = vizObj.transform.localScale; ls.x = Mathf.Sqrt(Vector2.SqrMagnitude(edge.v0.point - edge.v1.point)) / 2.0f; ls.y = selectedCenter.elevation - c.elevation; vizObj.transform.localScale = ls; vizObj.transform.SetParent(this.transform); edge.gameObjectRamp.Add(vizObj); bRescanNavGraph = true; return; } } } } }
private void AddToCenterList(List<Center> v, Center x) { if (x != null && v.IndexOf(x) < 0) { v.Add(x); } }
private Comparison<Corner> ClockwiseComparison(Center center) { Comparison<Corner> result = (a, b) => { return (int)(((a.point.x - center.point.x) * (b.point.y - center.point.y) - (b.point.x - center.point.x) * (a.point.y - center.point.y)) * 1000); }; return result; }
private static void AddCorner(Center topLeft, int x, int y) { if (topLeft.point.x != x || topLeft.point.y != y) topLeft.corners.Add(new Corner { ocean = true, point = new Vector2(x, y) }); }
static Biome GetBiome(Center p) { // if (p.ocean) // { // return Biome.Ocean; // } // else if (p.water) // { // if (p.elevation < 0.1) return Biome.Marsh; // if (p.elevation > 0.8) return Biome.Ice; // return Biome.Lake; // } // else if (p.coast) // { // return Biome.Beach; // } // else if (p.elevation > 0.8) // { // if (p.moisture > 0.50) return Biome.Snow; // else if (p.moisture > 0.33) return Biome.Tundra; // else if (p.moisture > 0.16) return Biome.Bare; // else return Biome.Scorched; // } // else if (p.elevation > 0.6) // { // if (p.moisture > 0.66) return Biome.Taiga; // else if (p.moisture > 0.33) return Biome.Shrubland; // else return Biome.TemperateDesert; // } // else if (p.elevation > 0.3) // { // if (p.moisture > 0.83) return Biome.TemperateRainForest; // else if (p.moisture > 0.50) return Biome.TemperateDeciduousForest; // else if (p.moisture > 0.16) return Biome.Grassland; // else return Biome.TemperateDesert; // } // else // { // if (p.moisture > 0.66) return Biome.TropicalRainForest; // else if (p.moisture > 0.33) return Biome.TropicalSeasonalForest; // else if (p.moisture > 0.16) return Biome.Grassland; // else return Biome.SubtropicalDesert; // } if (p.ocean) { return Biome.Ocean; } else if (p.water) { return Biome.Marsh; } else if (p.coast) { return Biome.Beach; } else if (p.elevation > 0.7) { return Biome.TemperateRainForest; } else if (p.elevation < 0.5) { if (p.moisture < 0.2) return Biome.Lava; else if (p.moisture < 0.25) return Biome.TemperateDesert; else return Biome.Grassland; } else { return Biome.RockLand; } }
private void BuildGraph(IEnumerable <Vector2> points, Delaunay.Voronoi voronoi) { // Build graph data structure in 'edges', 'centers', 'corners', // based on information in the Voronoi results: point.neighbors // will be a list of neighboring points of the same type (corner // or center); point.edges will be a list of edges that include // that point. Each edge connects to four points: the Voronoi edge // edge.{v0,v1} and its dual Delaunay triangle edge edge.{d0,d1}. // For boundary polygons, the Delaunay edge will have one null // point, and the Voronoi edge may be null. var libedges = voronoi.Edges(); var centerLookup = new Dictionary <Vector2?, Center>(); // Build Center objects for each of the points, and a lookup map // to find those Center objects again as we build the graph foreach (var point in points) { var p = new Center { index = centers.Count, point = point }; centers.Add(p); centerLookup[point] = p; } // Workaround for Voronoi lib bug: we need to call region() // before Edges or neighboringSites are available foreach (var p in centers) { voronoi.Region(p.point); } foreach (var libedge in libedges) { var dedge = libedge.DelaunayLine(); var vedge = libedge.VoronoiEdge(); // Fill the graph data. Make an Edge object corresponding to // the edge from the voronoi library. var edge = new Edge { index = edges.Count, river = 0, // Edges point to corners. Edges point to centers. v0 = MakeCorner(vedge.p0), v1 = MakeCorner(vedge.p1), d0 = centerLookup[dedge.p0], d1 = centerLookup[dedge.p1] }; if (vedge.p0.HasValue && vedge.p1.HasValue) { edge.midpoint = Vector2Extensions.Interpolate(vedge.p0.Value, vedge.p1.Value, 0.5f); } edges.Add(edge); // Centers point to edges. Corners point to edges. if (edge.d0 != null) { edge.d0.borders.Add(edge); } if (edge.d1 != null) { edge.d1.borders.Add(edge); } if (edge.v0 != null) { edge.v0.protrudes.Add(edge); } if (edge.v1 != null) { edge.v1.protrudes.Add(edge); } // Centers point to centers. if (edge.d0 != null && edge.d1 != null) { AddToCenterList(edge.d0.neighbors, edge.d1); AddToCenterList(edge.d1.neighbors, edge.d0); } // Corners point to corners if (edge.v0 != null && edge.v1 != null) { AddToCornerList(edge.v0.adjacent, edge.v1); AddToCornerList(edge.v1.adjacent, edge.v0); } // Centers point to corners if (edge.d0 != null) { AddToCornerList(edge.d0.corners, edge.v0); AddToCornerList(edge.d0.corners, edge.v1); } if (edge.d1 != null) { AddToCornerList(edge.d1.corners, edge.v0); AddToCornerList(edge.d1.corners, edge.v1); } // Corners point to centers if (edge.v0 != null) { AddToCenterList(edge.v0.touches, edge.d0); AddToCenterList(edge.v0.touches, edge.d1); } if (edge.v1 != null) { AddToCenterList(edge.v1.touches, edge.d0); AddToCenterList(edge.v1.touches, edge.d1); } } // TODO: use edges to determine these var topLeft = centers.OrderBy(p => p.point.x + p.point.y).First(); AddCorner(topLeft, 0, 0); var bottomRight = centers.OrderByDescending(p => p.point.x + p.point.y).First(); AddCorner(bottomRight, Width, Height); var topRight = centers.OrderByDescending(p => Width - p.point.x + p.point.y).First(); AddCorner(topRight, 0, Height); var bottomLeft = centers.OrderByDescending(p => p.point.x + Height - p.point.y).First(); AddCorner(bottomLeft, Width, 0); // required for polygon fill foreach (var center in centers) { center.corners.Sort(ClockwiseComparison(center)); } }
public Edge lookupEdgeFromCenter(Center p, Center r) { foreach (var edge in p.borders) { if (edge.d0 == r || edge.d1 == r) return edge; } return null; }
static Biome GetBiome(Center p) { if (p.ocean) { return Biome.Ocean; } else if (p.water) { if (p.elevation < 0.1) return Biome.Marsh; if (p.elevation > 0.8) return Biome.Ice; return Biome.Lake; } else if (p.coast) { return Biome.Beach; } else if (p.elevation > 0.8) { if (p.moisture > 0.50) return Biome.Snow; else if (p.moisture > 0.33) return Biome.Tundra; else if (p.moisture > 0.16) return Biome.Bare; else return Biome.Scorched; } else if (p.elevation > 0.6) { if (p.moisture > 0.66) return Biome.Taiga; else if (p.moisture > 0.33) return Biome.Shrubland; else return Biome.TemperateDesert; } else if (p.elevation > 0.3) { if (p.moisture > 0.83) return Biome.TemperateRainForest; else if (p.moisture > 0.50) return Biome.TemperateDeciduousForest; else if (p.moisture > 0.16) return Biome.Grassland; else return Biome.TemperateDesert; } else { if (p.moisture > 0.66) return Biome.TropicalRainForest; else if (p.moisture > 0.33) return Biome.TropicalSeasonalForest; else if (p.moisture > 0.16) return Biome.Grassland; else return Biome.SubtropicalDesert; } }
public void PlaceDoor(float x, float y) { Debug.Log("PlaceDoor"); Assets.Map.Center selectedCenter = Graph.centers.FirstOrDefault(p => p.PointInside(x, y)); if (selectedCenter == null) { Debug.Log("PlaceDoor: selectedCenter is null"); return; } // Generate List of edges which are valid for door placement. List <Assets.Map.Edge> validDoorEdges = new List <Assets.Map.Edge> (); for (int edgeIndex = 0; edgeIndex < selectedCenter.borders.Count; edgeIndex++) { Assets.Map.Edge selectedEdge = selectedCenter.borders[edgeIndex]; if (selectedEdge.v0 != null && selectedEdge.v1 != null) { if (Vector3.Magnitude(selectedEdge.v0.point - selectedEdge.v1.point) > 0) { validDoorEdges.Add(selectedEdge); } } } // remove existing door Viz game objects around selected center & store index of removed door Viz. int selectedEdgeIndex = 0; bool bRemovedDoor = false; for (int edgeIndex = 0; edgeIndex < validDoorEdges.Count; edgeIndex++) { Assets.Map.Edge selectedEdge = validDoorEdges[edgeIndex]; if (selectedEdge.gameObjectDoorViz.Count > 0) { selectedEdge.gameObjectDoorViz.ForEach(_gfx => Object.Destroy(_gfx)); selectedEdge.gameObjectDoorViz.Clear(); selectedEdgeIndex = edgeIndex; bRemovedDoor = true; } } // door placement will be at next edge index. if (bRemovedDoor == true) { selectedEdgeIndex++; } // this condition is used to define a state where no doors will be attached to the selected tile if (selectedEdgeIndex >= validDoorEdges.Count) { return; } Assets.Map.Edge edge = validDoorEdges[selectedEdgeIndex]; Assets.Map.Center adjCenter; // may be at either d0 or d1 if (edge.d0 == selectedCenter) // todo: floating point equaulity may break with non-integer floats. { adjCenter = edge.d1; } else { adjCenter = edge.d0; } int thisElevation = (int)selectedCenter.elevation; if (edge.v0 != null && edge.v1 != null) //graph border tiles may be null { //VIZ Vector3 newPos = (new Vector3(edge.v0.point.x, 0, edge.v0.point.y) + new Vector3(edge.v1.point.x, 0, edge.v1.point.y)) / 2; newPos.y = thisElevation; GameObject vizObj = Object.Instantiate(assetLibrary.GetComponent <AssetLibrary>().VizPrefabArch, newPos, Quaternion.identity) as GameObject; vizObj.name = "VizPrefabArch"; // flag MeshFilter game objects as viz layer MeshFilter[] childmf = vizObj.GetComponentsInChildren <MeshFilter>(); int ct = 0; while (ct < childmf.Length) { MeshFilter cmf = childmf[ct]; if (cmf != null) { cmf.gameObject.layer = 10; } ct++; } //rotate to angle of edge face float yAngle = Vector3.Angle(new Vector3(0, 0, 1), new Vector3(selectedCenter.point.x, 0, selectedCenter.point.y) - new Vector3(adjCenter.point.x, 0, adjCenter.point.y)); if (adjCenter.point.x > selectedCenter.point.x) { vizObj.transform.Rotate(0, -yAngle, 0); } else { vizObj.transform.Rotate(0, yAngle, 0); } Vector3 ls = vizObj.transform.localScale; ls.x = Mathf.Sqrt(Vector2.SqrMagnitude(edge.v0.point - edge.v1.point)); vizObj.transform.localScale = ls; vizObj.transform.SetParent(this.transform); edge.gameObjectDoorViz.Add(vizObj); } }