public void CreatePathDebug(TerrainManager TerrainManager_, he.TerrainTileHandle From, he.TerrainTileHandle To) { if (actualTask != null) actualTask.Stop(); actualTask = new utils.Task(CreatePathDebug_CoRo(TerrainManager_, From, To)); }
//! Create A* path. public he.TerrainTileHandle[] CreatePath(TerrainManager TerrainManager_, he.TerrainTileHandle From, he.TerrainTileHandle To) { lastPath = new script.AStarPathMap(TerrainManager_, From, To); while (lastPath.RunOnce() == script.AStarPathMap.State.WAIT) ; return lastPath.Path(); }
public System.Collections.IEnumerator CreatePathDebug_CoRo(TerrainManager TerrainManager_, he.TerrainTileHandle From, he.TerrainTileHandle To) { lastPath = new script.AStarPathMap(TerrainManager_, From, To); script.AStarPathMap.State state; do { yield return new WaitForSeconds(time); state = lastPath.RunOnce(); } while (state == script.AStarPathMap.State.WAIT); }
//! Delete the active terrain manager stuff. private static void ClearTerrain(he.script.TerrainManager Terrain) { // Get ALL terrain partitions, not only referenced (there could // be the one left when some error occurred during destroying it, // and aren't referenced inside terrain manager anywhere). var terrain_partitions_all = Terrain.GetComponentsInChildren<he.script.TerrainPartition>(); foreach (var terrain_partition in terrain_partitions_all) { // Destroy mesh as first AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(terrain_partition.GetComponent<MeshFilter>().sharedMesh)); // Destroy GO GameObject.DestroyImmediate(terrain_partition.gameObject); } }
//! Create mesh for partition. public Mesh CreateMesh(he.TerrainTileSet TileSet) { // Create vertex array Vector3[] array_vec = new Vector3[PARTITION_WIDTH * PARTITION_HEIGHT * 4]; // Create triangles array int[] array_tri = new int[PARTITION_WIDTH * PARTITION_HEIGHT * 6]; // Create UV arrays Vector2[] uv1 = new Vector2[array_vec.Length]; Vector2[] uv2 = new Vector2[array_vec.Length]; Vector4[] uv3 = new Vector4[array_vec.Length]; // Go through all tiles for (int i = 0, last_vertex = 0; i < PARTITION_HEIGHT; ++i) { for (int j = 0; j < PARTITION_WIDTH; ++j) { // Compute actual tile index for arry int tile_index = j + i * PARTITION_WIDTH; // Get Tile he.TerrainTile tile = m_Tiles[tile_index]; // Create vertices array_vec[GetVertexIndex(j, i)] = TileVertex(j, i, 0); array_vec[GetVertexIndex(j, i) + 1] = TileVertex(j, i, 1); array_vec[GetVertexIndex(j, i) + 2] = TileVertex(j, i, 2); array_vec[GetVertexIndex(j, i) + 3] = TileVertex(j, i, 3); last_vertex += 4; // Get the tile material types byte mat_v0 = tile.GetTerrainType(he.TerrainTile.Vertex.NORTH), mat_v1 = tile.GetTerrainType(he.TerrainTile.Vertex.WEST), mat_v2 = tile.GetTerrainType(he.TerrainTile.Vertex.SOUTH), mat_v3 = tile.GetTerrainType(he.TerrainTile.Vertex.EAST); // Get 1. and 2. material byte mat_1 = mat_v0; byte mat_2 = mat_1; if (mat_v0 != mat_v1) mat_2 = mat_v1; else if (mat_v0 != mat_v2) mat_2 = mat_v2; else if (mat_v0 != mat_v3) mat_2 = mat_v3; // Get alpha splat index byte alpha_index = 1; alpha_index |= (byte)((mat_v1 == mat_1) ? 2 : 0); alpha_index |= (byte)((mat_v2 == mat_1) ? 4 : 0); alpha_index |= (byte)((mat_v3 == mat_1) ? 8 : 0); // If materials need to be inverted if (alpha_index > 7) { byte mat_helper = mat_1; mat_1 = mat_2; mat_2 = mat_helper; alpha_index = (byte)(~alpha_index & 15); } // Get the primary tile type information he.TextureAtlasInfo primary_mat_info = TileSet.GetTileType(mat_1, tile.variant); // Get secondary tile type information he.TextureAtlasInfo secondary_mat_info = TileSet.GetTileType(mat_2, tile.variant); // Get the alpha splat info for tile he.TextureAtlasInfo alpha_splat_mat_info = TileSet.splatUsed.GetSplat(alpha_index); // Texture coordinates uv1[last_vertex - 4] = new Vector2(primary_mat_info.uvOffsetW + primary_mat_info.uvWidth / 2, primary_mat_info.uvOffsetH); uv1[last_vertex - 3] = new Vector2(primary_mat_info.uvOffsetW, primary_mat_info.uvOffsetH - primary_mat_info.uvHeight / 2); uv1[last_vertex - 2] = new Vector2(primary_mat_info.uvOffsetW + primary_mat_info.uvWidth / 2, primary_mat_info.uvOffsetH - primary_mat_info.uvHeight); uv1[last_vertex - 1] = new Vector2(primary_mat_info.uvOffsetW + primary_mat_info.uvWidth, primary_mat_info.uvOffsetH - primary_mat_info.uvHeight / 2); uv2[last_vertex - 4] = new Vector2(secondary_mat_info.uvOffsetW + secondary_mat_info.uvWidth / 2, secondary_mat_info.uvOffsetH); uv2[last_vertex - 3] = new Vector2(secondary_mat_info.uvOffsetW, secondary_mat_info.uvOffsetH - secondary_mat_info.uvHeight / 2); uv2[last_vertex - 2] = new Vector2(secondary_mat_info.uvOffsetW + secondary_mat_info.uvWidth / 2, secondary_mat_info.uvOffsetH - secondary_mat_info.uvHeight); uv2[last_vertex - 1] = new Vector2(secondary_mat_info.uvOffsetW + secondary_mat_info.uvWidth, secondary_mat_info.uvOffsetH - secondary_mat_info.uvHeight / 2); uv3[last_vertex - 4] = new Vector4(alpha_splat_mat_info.uvOffsetW + alpha_splat_mat_info.uvWidth / 2, alpha_splat_mat_info.uvOffsetH, 0); uv3[last_vertex - 3] = new Vector4(alpha_splat_mat_info.uvOffsetW, alpha_splat_mat_info.uvOffsetH - alpha_splat_mat_info.uvHeight / 2, 0, 0); uv3[last_vertex - 2] = new Vector4(alpha_splat_mat_info.uvOffsetW + alpha_splat_mat_info.uvWidth / 2, alpha_splat_mat_info.uvOffsetH - alpha_splat_mat_info.uvHeight, 0, 0); uv3[last_vertex - 1] = new Vector4(alpha_splat_mat_info.uvOffsetW + alpha_splat_mat_info.uvWidth, alpha_splat_mat_info.uvOffsetH - alpha_splat_mat_info.uvHeight / 2, 0, 0); // Create triangles int triangle_index = GetTriIndex(j, i); array_tri[triangle_index] = last_vertex - 4; array_tri[triangle_index + 1] = last_vertex - 1; array_tri[triangle_index + 2] = last_vertex - 3; array_tri[triangle_index + 3] = last_vertex - 3; array_tri[triangle_index + 4] = last_vertex - 1; array_tri[triangle_index + 5] = last_vertex - 2; // Save triangles int triangle_index_raw = j * 2 + i * PARTITION_WIDTH * 2; } } Mesh mesh = new Mesh(); mesh.vertices = array_vec; mesh.triangles = array_tri; mesh.uv = uv1; mesh.uv2 = uv2; mesh.tangents = uv3; mesh.RecalculateNormals(); // Set mesh and material GetComponent<MeshFilter>().mesh = mesh; GetComponent<MeshCollider>().sharedMesh = mesh; GetComponent<MeshRenderer>().sharedMaterial = Resources.Load("Materials/" + TileSet.materialName, typeof(Material)) as Material; // Save the mesh return mesh; }
public void This(int PartitionX, int PartitionY, he.TerrainTileSet TileSet) { m_PositionX = PartitionX; m_PositionY = PartitionY; // Create tiles m_Tiles = new he.TerrainTile[PARTITION_WIDTH * PARTITION_HEIGHT]; System.Random rnd = new System.Random(); for (int j = 0; j < PARTITION_HEIGHT; ++j) { for (int i = 0; i < PARTITION_WIDTH; ++i) { // Need to set all tiles as walkable, because we don't know // here which tiles are the ones at the border. It should // be set somewhere outside. \FIXME // Set random variant he.TerrainTile.Type tile_type = he.TerrainTile.Type.REGULAR; he.TerrainTile tile = new he.TerrainTile(i, j, tile_type, (byte)rnd.Next(0, 7)); // tile.variant = 0; m_Tiles[i + j * PARTITION_WIDTH] = tile; } } m_Properties = new Dictionary<ushort, he.TerrainTileProperty>(); m_NonMoveableMap = new Dictionary<string, ushort>(); }
public void This(ushort Width, ushort Height, he.TerrainTileSet TileSet) { m_Width = Width; m_Height = Height; m_Partitions = new TerrainPartition[m_Width * m_Height]; // Create partitions for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { TerrainPartition terrain_comp = CreateTerrainPartition(j, i); // Add to list of partitions m_Partitions[j + i * width] = terrain_comp; // Call "constructor" terrain_comp.This(j, i, TileSet); } } System.Random rnd = new System.Random(); // Set some random tile for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { var terrain_comp = m_Partitions[j + i * width].GetComponent<TerrainPartition>(); for (int k = 0; k < 10; ++k) { SetTileTerrainType( new TerrainTileHandle(rnd.Next(0, TerrainPartition.PARTITION_WIDTH), rnd.Next(0, TerrainPartition.PARTITION_HEIGHT), j, i), (byte)rnd.Next(0, 2) ); } // Create mesh terrain_comp.CreateMesh(TileSet); } } }
public static Direction GetDirection(he.TerrainTileHandle From, he.TerrainTileHandle To) { Direction dir = Direction.NONE; // Same partition { // Same y if (From.y == To.y) { if ((From.partitionX == To.partitionX && From.x < To.x) || From.partitionX < To.partitionX) dir = Direction.EAST; else dir = Direction.WEST; } else { int y_diff = From.y - To.y; int x_diff = From.x - To.x; int y_partition_diff = From.partitionY - To.partitionY; int x_partition_diff = From.partitionX - To.partitionX; if (y_partition_diff != 0) { if (y_partition_diff < 0) y_diff = y_diff -TerrainPartition.PARTITION_HEIGHT; else y_diff = y_diff + TerrainPartition.PARTITION_HEIGHT; } if (x_partition_diff != 0) { if (x_partition_diff < 0) x_diff = TerrainPartition.PARTITION_WIDTH - x_diff; else x_diff = TerrainPartition.PARTITION_WIDTH + x_diff; if (From.y % 2 == 1) x_diff *= -1; } // Non-even y if (From.y % 2 == 1) { switch (y_diff) { // Row up case 1: if (x_diff == 0) dir = Direction.NORTH_WEST; else if (x_diff < 0) dir = Direction.NORTH_EAST; break; // Row down case -1: if (x_diff == 0) dir = Direction.SOUTH_WEST; else if (x_diff < 0) dir = Direction.SOUTH_EAST; break; // 2 Row up case 2: if (x_diff == 0) dir = Direction.NORTH; break; // 2 Row down case -2: if (x_diff == 0) dir = Direction.SOUTH; break; } } else { switch (y_diff) { // Row up case 1: if (x_diff == 0) dir = Direction.NORTH_EAST; else if (x_diff > 0) dir = Direction.NORTH_WEST; break; // Row down case -1: if (x_diff == 0) dir = Direction.SOUTH_EAST; else if (x_diff > 0) dir = Direction.SOUTH_WEST; break; // 2 Row up case 2: if (x_diff == 0) dir = Direction.NORTH; break; // 2 Row down case -2: if (x_diff == 0) dir = Direction.SOUTH; break; } } } } return dir; }
//! Get tile in given direction and distance. public TerrainTileHandle GetTile(TerrainTileHandle Tile, he.Direction Dir, ushort Step) { TerrainTileHandle out_tile = Tile; for (ushort i = 0; i < Step; ++i) { // Break if we are out if (out_tile == null) break; out_tile = GetTile(out_tile, Dir); } return out_tile; }
//! Set tile terrain type. public void SetTileTerrainType(he.TerrainTileHandle TileHandle, byte TerrainType) { he.TerrainTile tile = GetTile(TileHandle); // Set terrain type for base tile tile.SetTerrainType(TerrainTile.Vertex.NORTH, TerrainType); tile.SetTerrainType(TerrainTile.Vertex.WEST, TerrainType); tile.SetTerrainType(TerrainTile.Vertex.SOUTH, TerrainType); tile.SetTerrainType(TerrainTile.Vertex.EAST, TerrainType); // Must set for neighbors he.TerrainTileHandle[] near_neighbors = GetAllNeighbors(TileHandle); if (near_neighbors[0] != null) GetTile(near_neighbors[0]).SetTerrainType(TerrainTile.Vertex.SOUTH, TerrainType); if (near_neighbors[1] != null) { GetTile(near_neighbors[1]).SetTerrainType(TerrainTile.Vertex.WEST, TerrainType); GetTile(near_neighbors[1]).SetTerrainType(TerrainTile.Vertex.SOUTH, TerrainType); } if (near_neighbors[2] != null) GetTile(near_neighbors[2]).SetTerrainType(TerrainTile.Vertex.WEST, TerrainType); if (near_neighbors[3] != null) { GetTile(near_neighbors[3]).SetTerrainType(TerrainTile.Vertex.NORTH, TerrainType); GetTile(near_neighbors[3]).SetTerrainType(TerrainTile.Vertex.WEST, TerrainType); } if (near_neighbors[4] != null) GetTile(near_neighbors[4]).SetTerrainType(TerrainTile.Vertex.NORTH, TerrainType); if (near_neighbors[5] != null) { GetTile(near_neighbors[5]).SetTerrainType(TerrainTile.Vertex.NORTH, TerrainType); GetTile(near_neighbors[5]).SetTerrainType(TerrainTile.Vertex.EAST, TerrainType); } if (near_neighbors[6] != null) GetTile(near_neighbors[6]).SetTerrainType(TerrainTile.Vertex.EAST, TerrainType); if (near_neighbors[7] != null) { GetTile(near_neighbors[7]).SetTerrainType(TerrainTile.Vertex.SOUTH, TerrainType); GetTile(near_neighbors[7]).SetTerrainType(TerrainTile.Vertex.EAST, TerrainType); } }
//! Get neighbor tile. public he.TerrainTileHandle GetTile(he.TerrainTileHandle Tile, Direction Dir) { int partition_x = Tile.partitionX; int partition_y = Tile.partitionY; int x = Tile.x; int y = Tile.y; switch (Dir) { case Direction.NORTH: y -= 2; break; case Direction.NORTH_EAST: --y; x += (int)(Tile.y & 1); break; case Direction.EAST: ++x; break; case Direction.SOUTH_EAST: ++y; x += (int)(Tile.y & 1); break; case Direction.SOUTH: y += 2; break; case Direction.SOUTH_WEST: ++y; x += (int)((Tile.y & 1) - 1); break; case Direction.WEST: --x; break; case Direction.NORTH_WEST: --y; x += (int)((Tile.y & 1) - 1); break; } // If we're past partition if (x >= TerrainPartition.PARTITION_WIDTH) { ++partition_x; x %= TerrainPartition.PARTITION_WIDTH; } else if (x < 0) { --partition_x; x = TerrainPartition.PARTITION_WIDTH + x; } if (y >= TerrainPartition.PARTITION_HEIGHT) { ++partition_y; y %= TerrainPartition.PARTITION_HEIGHT; } else if (y < 0) { --partition_y; y = TerrainPartition.PARTITION_HEIGHT + y; } return GetTileChecked(partition_x, partition_y, x, y); }
//! Get tile instance. public he.TerrainTile GetTile(he.TerrainTileHandle TileHandle) { return GetPartition((ushort)TileHandle.partitionX, (ushort)TileHandle.partitionY).GetTile(TileHandle.x, TileHandle.y); }
//! Get position of center of tile. public Vector3 GetPosition(he.TerrainTileHandle Tile) { return new Vector3(GetPosition(Tile, 1).x, 0, GetPosition(Tile, 0).z); }
//! Get tile position for given tile. public Vector3 GetPosition(he.TerrainTileHandle Tile, short Vertex) { return GetPartition((ushort)Tile.partitionX, (ushort)Tile.partitionY).transform.TransformPoint(TerrainPartition.TileVertex(Tile.x, Tile.y, Vertex)); }
//! Get the all neighbors. /*! The tiles are returned in this order: NORTH, NORTH-EAST, EAST, SOUTH-EAST, SOUTH, SOUTH-WEST, WEST, NORTH-WEST. */ public he.TerrainTileHandle[] GetAllNeighbors(he.TerrainTileHandle Tile) { var output = new he.TerrainTileHandle[8]; // Traverse all neighbors tiles for (Direction direction = Direction.NORTH; direction <= Direction.NORTH_WEST; direction = (Direction)(direction + 1)) { // Add it to container if tile exist output[(int)direction - 1] = GetTile(Tile, direction); } return output; }