public int NearestZLevel(int x, int y, int z) { MapColumn c = TileColumnAt(x, y); int dz = int.MaxValue; MapTile closest = null; if (c == null || c.Count == 0) { return(0); } for (int i = 0; i < c.Count; i++) { MapTile s = c.At(i); MapTile next = i + 1 >= c.Count ? null : c.At(i + 1); if (next == null || next.z > s.maxZ) { int thisDz = (int)Mathf.Abs((s.avgZ) - z); if (thisDz < dz) { dz = thisDz; closest = s; } } } return(closest.avgZ); }
public MapTile TileAt(int x, int y, int z) { if (x < 0 || y < 0 || x >= _size.x || y >= _size.y || z < 0) { return(null); } if (stacks == null) { return(null); } MapColumn c = TileColumnAt(x, y); if (c == null) { return(null); } for (int i = 0; i < c.Count; i++) { MapTile t = c.At(i); if (t.ContainsZ(z)) { return(MapTileIsNull(t) ? null : t); } if (t.IsAboveZ(z)) { return(null); } } return(null); }
public void AddIsoTileAt(int x, int y, int z) { if (stacks == null) { ResetStacks(Vector2.zero); } MapColumn stackC = TileColumnAt(x, y); MapTile stack = null; bool added = false; if (stackC == null || stackC.Count == 0) { stack = new MapTile(x, y, z); stack.serializeHackUsable = true; SetTileStackAt(stack, x, y); added = true; } else { MapTile newStack = new MapTile(x, y, z); newStack.serializeHackUsable = true; bool present = false; for (int i = 0; i < stackC.Count; i++) { stack = stackC.At(i); if (stack.IsAboveZ(z)) { stackC.Insert(i, newStack); present = true; added = true; break; } else if (stack.ContainsZ(z)) { present = true; break; } } if (!present) { if (stack.maxZ == z && stack.maxHeight != 1) { //don't propagate heights, just clobber the old ones int max = stack.maxHeight; //stack.next.heights = stack.heights; //stack.heights = new int[]{1,1,1,1}; stack.heights = new int[] { max, max, max, max }; } stackC.Add(newStack); added = true; } } if (added) { RemakeMesh(); } }
public int NextZLevel(int x, int y, int z, bool wrap = false) { MapColumn mc = TileColumnAt(x, y); if (mc == null) { return(-1); } MapTile ret = null; for (int i = 0; i < mc.Count; i++) { MapTile t = mc.At(i); if (MapTileIsNull(t)) { continue; } if (i < mc.Count - 1 && mc.At(i + 1).z == t.maxZ) { //skip, we're in the middle of a stack continue; } if (ret == null && wrap) { ret = t; } //get bottom //if t's maxZ is above z, set ret to it and break if (t.maxZ > z) { ret = t; break; } } if (ret == null) { return(-1); } return(ret.maxZ - 1); }
public int PrevZLevel(int x, int y, int z, bool wrap = true) { MapColumn mc = TileColumnAt(x, y); if (mc == null) { return(-1); } MapTile ret = null; for (int i = mc.Count - 1; i >= 0; i--) { MapTile t = mc.At(i); if (MapTileIsNull(t)) { continue; } if (i < mc.Count - 1 && mc.At(i + 1).z == t.maxZ) { //skip, we're in the middle of a stack continue; } if (ret == null && wrap) { ret = t; } //get top //if t's maxZ is below z, set ret to it and break if (t.maxZ < z) { ret = t; break; } } if (ret == null) { return(-1); } return(ret.maxZ - 1); }
public int[] ZLevelsWithinLimits(int x, int y, int minZ, int maxZ) { if (x < 0 || y < 0 || x >= size.x || y >= size.y) { return(new int[0]); } MapColumn c = TileColumnAt(x, y); if (c == null || c.Count == 0) { return(new int[0]); } List <int> zLevels = new List <int>(); for (int i = 0; i < c.Count; i++) { MapTile t = c.At(i); //skip anybody with a tile immediately above them if (i + 1 < c.Count) { if (c.At(i + 1).z <= t.maxZ) { continue; } else { //it's fine, keep going } } //skip tiles that are not within range if (minZ < 0 || maxZ < 0 || (t.avgZ > minZ && t.avgZ <= maxZ)) { zLevels.Add(t.avgZ); } } return(zLevels.ToArray()); }
MapTile NextTile(MapTile t) { MapColumn stack = TileColumnAt(t.x, t.y); if (stack == null) { return(null); } int tidx = stack.IndexOf(t); if (tidx == -1) { return(null); } if (tidx + 1 >= stack.Count) { return(null); } /* Debug.Log("next after "+t+" at "+tidx+" is "+stack.At(tidx+1)+" where count is "+stack.Count);*/ return(stack.At(tidx + 1)); }
public void RemoveTileSpecAt(int i) { for (int mi = 0; mi < stacks.Length; mi++) { MapColumn tl = stacks[mi]; if (tl == null) { continue; } for (int ti = 0; ti < tl.Count; ti++) { MapTile t = tl.At(ti); if (!MapTileIsNull(t)) { t.AdjustTileSpecsAfterRemoving(i); } } } tileSpecs.RemoveAt(i); RemakeTexture(); }
public void RemoveIsoTileAt(int x, int y, int z) { if (stacks == null) { //no tile to remove return; } MapColumn stackC = TileColumnAt(x, y); MapTile stack; if (stackC == null || stackC.Count == 0) { //no tile to remove return; } bool removed = false; for (int i = 0; i < stackC.Count; i++) { stack = stackC.At(i); if (stack.IsAboveZ(z)) { return; } if (stack.ContainsZ(z)) { stackC.RemoveAt(i); removed = true; break; } } if (removed) { RemakeMesh(); } }
void OnWizardCreate () { if(!map) { return; } StringBuilder exportStr = new StringBuilder(1024); Vector2 size = map.size; exportStr.Append("[\n"); for(int y = 0; y < size.y; y++) { exportStr.Append("\t["); for(int x = 0; x < size.x; x++) { MapColumn tc = map.TileColumnAt(x,y); if(tc.Count == 0) { exportStr.Append("[]"); } else { exportStr.Append("["); //emit Z range and tile, Z range and tile, Z range and tile... for(int i = 0; i < tc.Count; i++) { MapTile t = tc.At(i); int zMin = t.z; int h = t.maxHeight; exportStr.AppendFormat("{{{0},{1},cube}}",zMin,h); if(i < tc.Count-1) { exportStr.Append(","); } } exportStr.Append("]"); } if(x < size.x-1) { exportStr.Append(", "); } } exportStr.Append("]"); if(y < size.y-1) { exportStr.Append(","); } exportStr.Append("\n"); } exportStr.Append("]."); File.WriteAllText(Application.dataPath + "/"+map.name+"_export.txt", exportStr.ToString()); AssetDatabase.Refresh(); }
void RemakeMesh() { if (stacks == null) { return; } MeshFilter mf = GetComponent <MeshFilter>(); if (mf == null) { mf = gameObject.AddComponent <MeshFilter>(); } MeshRenderer mr = GetComponent <MeshRenderer>(); if (mr == null) { mr = gameObject.AddComponent <MeshRenderer>(); } MeshCollider mc = GetComponent <MeshCollider>(); if (mc == null) { mc = gameObject.AddComponent <MeshCollider>(); } if (mr.sharedMaterials.Length < 2 || mr.sharedMaterials[0] == null || mr.sharedMaterials[1] == null) { mr.sharedMaterials = new Material[] { new Material(Shader.Find("Transparent/Cutout/Diffuse")), new Material(Shader.Find("Transparent/Diffuse")) }; mr.sharedMaterials[1].color = Application.isPlaying ? Color.clear : new Color(0.7f, 0.7f, 1.0f, 0.5f); } if (mr.sharedMaterials[0].mainTexture != mainAtlas) { mr.sharedMaterials[0].mainTexture = mainAtlas; } if (mr.sharedMaterials[1].mainTexture != mainAtlas) { mr.sharedMaterials[1].mainTexture = mainAtlas; } Mesh mesh = mf.sharedMesh != null ? mf.sharedMesh : new Mesh(); mesh.Clear(); float height = _tileHeight; //FIXME: height assumption may be higher than necessary //24 vertices per so each gets a uv, we will say 20 units high Vector3[] vertices = new Vector3[(int)(_size.x * _size.y * 20 * 24)]; //10 tris, 3 indices per, we will say 20 units high int[] opaqueTriangles = new int[(int)(_size.x * _size.y * 20 * 10 * 3)]; Vector2[] uvs = new Vector2[vertices.Length]; int vertIdx = 0; int opaqueTriIdx = 0; //10 tris, 3 indices per, we will say 20 units high int[] transparentTriangles = new int[(int)(_size.x * _size.y * 20 * 10 * 3)]; int transparentTriIdx = 0; for (int i = 0; i < stacks.Length; i++) { MapColumn tlist = stacks[i]; if (tlist == null) { continue; } int y = i / (int)_size.x; int x = i - (y * (int)_size.x); for (int ti = 0; ti < tlist.Count; ti++) { MapTile t = tlist.At(ti); if (MapTileIsNull(t)) { Debug.Log("tile " + t + " at " + ti + " is null somehow"); } int z = t.z; int[] triangles = t.invisible ? transparentTriangles : opaqueTriangles; int triIdx = t.invisible ? transparentTriIdx : opaqueTriIdx; bool avoidNeighbors = t.maxHeight == 1 && t.noInsets && !t.invisible && NoInsetOrInvisibleNeighbors(x, y, t); float lx = (x + 0 + t.sideInsets[(int)Neighbors.FrontLeftIdx]) * _sideLength - _sideLength / 2; float fx = (x + 0 + t.sideInsets[(int)Neighbors.FrontLeftIdx]) * _sideLength - _sideLength / 2; float rx = (x + 1 - t.sideInsets[(int)Neighbors.BackRightIdx]) * _sideLength - _sideLength / 2; float bx = (x + 1 - t.sideInsets[(int)Neighbors.BackRightIdx]) * _sideLength - _sideLength / 2; float fy = (y + 0 + t.sideInsets[(int)Neighbors.FrontRightIdx]) * _sideLength - _sideLength / 2; float ry = (y + 0 + t.sideInsets[(int)Neighbors.FrontRightIdx]) * _sideLength - _sideLength / 2; float ly = (y + 1 - t.sideInsets[(int)Neighbors.BackLeftIdx]) * _sideLength - _sideLength / 2; float by = (y + 1 - t.sideInsets[(int)Neighbors.BackLeftIdx]) * _sideLength - _sideLength / 2; //TODO: include corner insets and their extra geometry //TODO: stairs and their extra geometry float zMinL = (z + 0 + t.sideInsets[(int)Neighbors.BottomIdx] + t.baselines[(int)Corners.Left] - 1) * height; float zMaxL = (z - t.sideInsets[(int)Neighbors.TopIdx] + t.heights[(int)Corners.Left] - 1) * height; float zMinF = (z + 0 + t.sideInsets[(int)Neighbors.BottomIdx] + t.baselines[(int)Corners.Front] - 1) * height; float zMaxF = (z - t.sideInsets[(int)Neighbors.TopIdx] + t.heights[(int)Corners.Front] - 1) * height; float zMinB = (z + 0 + t.sideInsets[(int)Neighbors.BottomIdx] + t.baselines[(int)Corners.Back] - 1) * height; float zMaxB = (z - t.sideInsets[(int)Neighbors.TopIdx] + t.heights[(int)Corners.Back] - 1) * height; float zMinR = (z + 0 + t.sideInsets[(int)Neighbors.BottomIdx] + t.baselines[(int)Corners.Right] - 1) * height; float zMaxR = (z - t.sideInsets[(int)Neighbors.TopIdx] + t.heights[(int)Corners.Right] - 1) * height; Vector3 bl = new Vector3(lx, zMinL, ly); Vector3 bf = new Vector3(fx, zMinF, fy); Vector3 bb = new Vector3(bx, zMinB, by); Vector3 br = new Vector3(rx, zMinR, ry); Vector3 tl = new Vector3(lx, zMaxL, ly); Vector3 tf = new Vector3(fx, zMaxF, fy); Vector3 tb = new Vector3(bx, zMaxB, by); Vector3 tr = new Vector3(rx, zMaxR, ry); Neighbors mask = NeighborsOfTile(x, y, z); if ((mask & Neighbors.Top) == 0 || !avoidNeighbors) { vertices[vertIdx + 0] = tf; //5 vertices[vertIdx + 1] = tl; //4 vertices[vertIdx + 2] = tr; //7 vertices[vertIdx + 3] = tb; //6 UVMap(t, Neighbors.Top, uvs, vertIdx); triangles[triIdx + 0 * 3 + 0] = vertIdx + 0; triangles[triIdx + 0 * 3 + 1] = vertIdx + 1; triangles[triIdx + 0 * 3 + 2] = vertIdx + 2; triangles[triIdx + 1 * 3 + 0] = vertIdx + 2; triangles[triIdx + 1 * 3 + 1] = vertIdx + 1; triangles[triIdx + 1 * 3 + 2] = vertIdx + 3; triIdx += 2 * 3; vertIdx += 4; } if ((mask & Neighbors.BackLeft) == 0 || !avoidNeighbors) { vertices[vertIdx + 0] = tl; //4 vertices[vertIdx + 1] = bl; //0 vertices[vertIdx + 2] = tb; //6 vertices[vertIdx + 3] = bb; //2 UVMap(t, Neighbors.BackLeft, uvs, vertIdx); triangles[triIdx + 0 * 3 + 0] = vertIdx + 0; triangles[triIdx + 0 * 3 + 1] = vertIdx + 1; triangles[triIdx + 0 * 3 + 2] = vertIdx + 2; triangles[triIdx + 1 * 3 + 0] = vertIdx + 2; triangles[triIdx + 1 * 3 + 1] = vertIdx + 1; triangles[triIdx + 1 * 3 + 2] = vertIdx + 3; triIdx += 2 * 3; vertIdx += 4; } if ((mask & Neighbors.FrontRight) == 0 || !avoidNeighbors) { vertices[vertIdx + 0] = bf; //1 vertices[vertIdx + 1] = tf; //5 vertices[vertIdx + 2] = br; //3 vertices[vertIdx + 3] = tr; //7 UVMap(t, Neighbors.FrontRight, uvs, vertIdx); triangles[triIdx + 0 * 3 + 0] = vertIdx + 0; triangles[triIdx + 0 * 3 + 1] = vertIdx + 1; triangles[triIdx + 0 * 3 + 2] = vertIdx + 2; triangles[triIdx + 1 * 3 + 0] = vertIdx + 2; triangles[triIdx + 1 * 3 + 1] = vertIdx + 1; triangles[triIdx + 1 * 3 + 2] = vertIdx + 3; triIdx += 2 * 3; vertIdx += 4; } if ((mask & Neighbors.FrontLeft) == 0 || !avoidNeighbors) { vertices[vertIdx + 0] = tl; //4 vertices[vertIdx + 1] = tf; //5 vertices[vertIdx + 2] = bl; //0 vertices[vertIdx + 3] = bf; //1 UVMap(t, Neighbors.FrontLeft, uvs, vertIdx); triangles[triIdx + 0 * 3 + 0] = vertIdx + 0; triangles[triIdx + 0 * 3 + 1] = vertIdx + 1; triangles[triIdx + 0 * 3 + 2] = vertIdx + 2; triangles[triIdx + 1 * 3 + 0] = vertIdx + 2; triangles[triIdx + 1 * 3 + 1] = vertIdx + 1; triangles[triIdx + 1 * 3 + 2] = vertIdx + 3; triIdx += 2 * 3; vertIdx += 4; } if ((mask & Neighbors.BackRight) == 0 || !avoidNeighbors) { vertices[vertIdx + 0] = bb; //2 vertices[vertIdx + 1] = br; //3 vertices[vertIdx + 2] = tb; //6 vertices[vertIdx + 3] = tr; //7 UVMap(t, Neighbors.BackRight, uvs, vertIdx); triangles[triIdx + 0 * 3 + 0] = vertIdx + 0; triangles[triIdx + 0 * 3 + 1] = vertIdx + 1; triangles[triIdx + 0 * 3 + 2] = vertIdx + 2; triangles[triIdx + 1 * 3 + 0] = vertIdx + 2; triangles[triIdx + 1 * 3 + 1] = vertIdx + 1; triangles[triIdx + 1 * 3 + 2] = vertIdx + 3; triIdx += 2 * 3; vertIdx += 4; } if (usesBottomFace && (((mask & Neighbors.Bottom) == 0) || !avoidNeighbors)) { vertices[vertIdx + 0] = bl; //0 vertices[vertIdx + 1] = bf; //1 vertices[vertIdx + 2] = bb; //2 vertices[vertIdx + 3] = br; //3 UVMap(t, Neighbors.Bottom, uvs, vertIdx); triangles[triIdx + 0 * 3 + 0] = vertIdx + 0; triangles[triIdx + 0 * 3 + 1] = vertIdx + 1; triangles[triIdx + 0 * 3 + 2] = vertIdx + 2; triangles[triIdx + 1 * 3 + 0] = vertIdx + 2; triangles[triIdx + 1 * 3 + 1] = vertIdx + 1; triangles[triIdx + 1 * 3 + 2] = vertIdx + 3; triIdx += 2 * 3; vertIdx += 4; } if (t.invisible) { transparentTriIdx = triIdx; } else { opaqueTriIdx = triIdx; } } } Array.Resize <Vector3>(ref vertices, vertIdx); Array.Resize <Vector2>(ref uvs, vertIdx); Array.Resize <int>(ref opaqueTriangles, opaqueTriIdx); Array.Resize <int>(ref transparentTriangles, transparentTriIdx); mesh.vertices = vertices; mesh.uv = uvs; mesh.subMeshCount = 2; mesh.SetTriangles(opaqueTriangles, 0); mesh.SetTriangles(transparentTriangles, 1); mesh.RecalculateNormals(); mesh.Optimize(); mf.sharedMesh = mesh; mc.convex = false; InvalidateOverlayMesh(); }