///<summary> ///Create a GameObject for each Tile with a defined type and thus potentially a prefab. ///</summary> static void CreateTileObjects( Map map, Map.Layer layer, Map.Layer.Chunk chunk, GameObject layerObject ) { var chunkPosition = new Vector3Int(chunk.x, layer.height - chunk.height - chunk.y, 0); for (var k = 0; k < chunk.gids.Length; ++k) { var gid = chunk.gids[k]; var tile = map.tiles[gid & 0x1ffffff]; if (!tile?.prefab) { continue; } // The 3 most significant bits indicate in what way the tile should be flipped. var diagonal = (gid >> 29) & 1; var vertical = (gid >> 30) & 1; var horizontal = (gid >> 31) & 1; var position = chunkPosition + new Vector3Int(k % chunk.width, k / chunk.width, 0); // Since a tile's GameObject is instantiated automatically in Edit Mode and *again* // in Play Mode, we can't use the built in approach, and instead have to // handle instantiation ourselves to avoid duplicate GameObjects. var gameObject = PrefabUtility.InstantiatePrefab( tile.prefab, layerObject.transform ) as GameObject; if (gameObject) { gameObject.name += $" {position.x},{position.y}"; gameObject.transform.localPosition = position; if (vertical == 1) { gameObject.transform.localRotation *= Quaternion.Euler(180f, 0f, 0f); gameObject.transform.localPosition -= gameObject.transform.up; } if (horizontal == 1) { gameObject.transform.localRotation *= Quaternion.Euler(0f, 180f, 0f); gameObject.transform.localPosition -= gameObject.transform.right; } if (diagonal == 1) { gameObject.transform.localRotation *= Quaternion.AngleAxis(180f, new Vector3(-1f, 1f, 0f)); gameObject.transform.localPosition -= gameObject.transform.up; gameObject.transform.localPosition -= gameObject.transform.right; } foreach (var component in gameObject.GetComponentsInChildren <MonoBehaviour>()) { Property.Apply(tile.properties, component); } } } }
///<summary> ///Get an array of all tiles in a chunk. ///</summary> static Tile[] GetTiles(Map map, Map.Layer layer, Map.Layer.Chunk chunk) { var tiles = new Tile[chunk.gids.Length]; for (var k = 0; k < tiles.Length; ++k) { tiles[k] = map.tiles[chunk.gids[k] & 0x1ffffff]; } return(tiles); }
///<summary> ///Flip all tiles in a chunk according to their 3 most significant flip bits, if any. ///</summary> static void FlipTiles(Tilemap tilemap, Map.Layer layer, Map.Layer.Chunk chunk) { var chunkPosition = new Vector3Int(chunk.x, layer.height - chunk.height - chunk.y, 0); for (var k = 0; k < chunk.gids.Length; ++k) { var gid = chunk.gids[k]; // The 3 most significant bits indicate in what way the tile should be flipped. if (gid >> 29 == 0) { continue; } var diagonal = (gid >> 29) & 1; var vertical = (gid >> 30) & 1; var horizontal = (gid >> 31) & 1; var position = chunkPosition + new Vector3Int(k % chunk.width, k / chunk.width, 0); var rotation = Quaternion.identity; // Flip tiles along X, Y, and diagonally based on the flip flags. if (vertical == 1) { rotation *= Quaternion.Euler(180f, 0f, 0f); } if (horizontal == 1) { rotation *= Quaternion.Euler(0f, 180f, 0f); } if (diagonal == 1) { rotation *= Quaternion.AngleAxis(180f, new Vector3(-1f, 1f, 0f)); } var transform = Matrix4x4.TRS(pos: Vector3.zero, rotation, s: Vector3.one); tilemap.SetTransformMatrix(position, transform); } }