public DoorInstance(OrthogonalLine doorLine, Vector2Int facingDirection, RoomBase connectedRoom, RoomInstance connectedRoomInstance) { this.doorLine = doorLine; this.facingDirection = facingDirection; this.connectedRoom = connectedRoom; this.connectedRoomInstance = connectedRoomInstance; this.isHorizontal = FacingDirection == Vector2Int.up || FacingDirection == Vector2Int.down; }
private static List <Vector3Int> GetTilesInsideOutline(RoomInstance roomInstance, bool useLocalPositions) { return(roomInstance .OutlinePolygon .GetAllPoints() .Select(x => new Vector3Int(x.x, x.y, 0)) .Select(x => useLocalPositions ? x - roomInstance.Position : x) .ToList()); }
/// <summary> /// Copies tiles from a given room template to given destination tilemaps. /// </summary> /// <remarks> /// One important aspect of this method is how to handle already existing tiles in destination tilemaps. /// /// When deleteNonNullTiles is true, it computes all non-null positions across all layers in the room template. /// After that, it deletes all tiles on these positions in destination tilemaps. /// /// When deleteTilesInsideOutline is true, it computes all tiles inside the outline of the room template and /// deletes them from the destination tilemaps. /// So even if there is a hole inside the room template, the position is still removed. /// /// deleteNonNullTiles and deleteTilesInsideOutline can be combined together. /// </remarks> /// <param name="roomInstance">Room instance to be copied to the destination tilemaps.</param> /// <param name="destinationTilemaps">List of destination tilemaps.</param> /// <param name="deleteNonNullTiles">Whether to delete non-null tiles from destination tilemaps.</param> /// <param name="deleteTilesInsideOutline">Whether to delete all tiles insides the outline from destination tilemaps.</param> public static void CopyTiles(RoomInstance roomInstance, List <Tilemap> destinationTilemaps, bool deleteNonNullTiles, bool deleteTilesInsideOutline) { var sourceTilemaps = RoomTemplateUtils.GetTilemaps(roomInstance.RoomTemplateInstance); sourceTilemaps = RoomTemplateUtils.GetTilemapsForCopying(sourceTilemaps); var tilesToRemove = new List <Vector3Int>(); if (deleteNonNullTiles) { var tiles = GetNonNullTiles(sourceTilemaps); tilesToRemove.AddRange(tiles.Select(x => x + roomInstance.Position)); } if (deleteTilesInsideOutline) { var tiles = GetTilesInsideOutline(roomInstance, false); tilesToRemove.AddRange(tiles); } RemoveTiles(destinationTilemaps, tilesToRemove); foreach (var sourceTilemap in sourceTilemaps) { var destinationTilemap = destinationTilemaps.FirstOrDefault(x => x.name == sourceTilemap.name); if (destinationTilemap == null) { continue; } foreach (var tilemapPosition in sourceTilemap.cellBounds.allPositionsWithin) { var tile = sourceTilemap.GetTile(tilemapPosition); if (tile != null) { destinationTilemap.SetTile(tilemapPosition + roomInstance.Position, tile); destinationTilemap.SetTransformMatrix(tilemapPosition + roomInstance.Position, sourceTilemap.GetTransformMatrix(tilemapPosition)); } } } }
/// <summary> /// Copies tiles from a given room template to given destination tilemaps. /// </summary> /// <remarks> /// One important aspect of this method is how to handle already existing tiles in destination tilemaps. /// /// When deleteNonNullTiles is true, it computes all non-null positions across all layers in the room template. /// After that, it deletes all tiles on these positions in destination tilemaps. /// /// When deleteTilesInsideOutline is true, it computes all tiles inside the outline of the room template and /// deletes them from the destination tilemaps. /// So even if there is a hole inside the room template, the position is still removed. /// /// deleteNonNullTiles and deleteTilesInsideOutline can be combined together. /// </remarks> /// <param name="roomInstance">Room instance to be copied to the destination tilemaps.</param> /// <param name="destinationTilemaps">List of destination tilemaps.</param> /// <param name="deleteNonNullTiles">Whether to delete non-null tiles from destination tilemaps.</param> /// <param name="deleteTilesInsideOutline">Whether to delete all tiles insides the outline from destination tilemaps.</param> public static void CopyTiles(RoomInstance roomInstance, List <Tilemap> destinationTilemaps, bool deleteNonNullTiles, bool deleteTilesInsideOutline) { PostProcessUtils.CopyTiles(roomInstance, destinationTilemaps, deleteNonNullTiles, deleteTilesInsideOutline); }
private static DoorInstance TransformDoorInfo(LayoutDoorGrid2D <RoomBase> doorInfo, RoomInstance connectedRoomInstance) { var doorLine = doorInfo.DoorLine; switch (doorLine.GetDirection()) { case OrthogonalLineGrid2D.Direction.Right: return(new DoorInstance(new OrthogonalLine(doorLine.From.ToUnityIntVector3(), doorLine.To.ToUnityIntVector3()), Vector2Int.up, connectedRoomInstance.Room, connectedRoomInstance)); case OrthogonalLineGrid2D.Direction.Left: return(new DoorInstance(new OrthogonalLine(doorLine.To.ToUnityIntVector3(), doorLine.From.ToUnityIntVector3()), Vector2Int.down, connectedRoomInstance.Room, connectedRoomInstance)); case OrthogonalLineGrid2D.Direction.Top: return(new DoorInstance(new OrthogonalLine(doorLine.From.ToUnityIntVector3(), doorLine.To.ToUnityIntVector3()), Vector2Int.left, connectedRoomInstance.Room, connectedRoomInstance)); case OrthogonalLineGrid2D.Direction.Bottom: return(new DoorInstance(new OrthogonalLine(doorLine.To.ToUnityIntVector3(), doorLine.From.ToUnityIntVector3()), Vector2Int.right, connectedRoomInstance.Room, connectedRoomInstance)); default: throw new ArgumentOutOfRangeException(); } }
public static GeneratedLevel TransformLayout(LayoutGrid2D <RoomBase> layout, LevelDescription levelDescription, GameObject rootGameObject) { // var layoutCenter = GetLayoutCenter(layout); var prefabToRoomTemplateMapping = levelDescription.GetPrefabToRoomTemplateMapping(); var corridorToConnectionMapping = levelDescription.GetCorridorToConnectionMapping(); // Prepare an object to hold instantiated room templates var roomTemplateInstancesRoot = new GameObject(GeneratorConstants.RoomsRootName); roomTemplateInstancesRoot.transform.parent = rootGameObject.transform; // Initialize rooms var layoutData = new Dictionary <RoomBase, RoomInstance>(); var layoutRooms = layout.Rooms.ToDictionary(x => x.Room, x => x); foreach (var layoutRoom in layoutRooms.Values) { var roomTemplatePrefab = prefabToRoomTemplateMapping.GetByValue(layoutRoom.RoomTemplate); // Instantiate room template var roomTemplateInstance = Object.Instantiate(roomTemplatePrefab); roomTemplateInstance.transform.SetParent(roomTemplateInstancesRoot.transform); roomTemplateInstance.name = $"{layoutRoom.Room.GetDisplayName()} - {roomTemplatePrefab.name}"; // Compute correct room position var position = layoutRoom.Position.ToUnityIntVector3(); roomTemplateInstance.transform.position = position; // Correct the position based on the grid // This is important when there is some cell spacing or when the level is isometric var tilemapsHolder = roomTemplateInstance.transform.Find(GeneratorConstants.TilemapsRootName).gameObject; if (tilemapsHolder != null) { var grid = tilemapsHolder.GetComponent <Grid>(); roomTemplateInstance.transform.position = grid.CellToLocal(position); } // Compute outline polygon var polygon = new Polygon2D(layoutRoom.Outline + layoutRoom.Position); var connection = layoutRoom.IsCorridor ? corridorToConnectionMapping[layoutRoom.Room] : null; var roomInstance = new RoomInstance(layoutRoom.Room, layoutRoom.IsCorridor, connection, roomTemplatePrefab, roomTemplateInstance, position, polygon); // Add room info to the GameObject var roomInfo = roomTemplateInstance.GetComponent <RoomInfo>(); if (roomInfo != null) { PostProcessUtils.Destroy(roomInfo); } roomInfo = roomTemplateInstance.AddComponent <RoomInfo>(); roomInfo.RoomInstance = roomInstance; layoutData.Add(layoutRoom.Room, roomInstance); } foreach (var roomInstance in layoutData.Values) { roomInstance.SetDoors(TransformDoorInfo(layoutRooms[roomInstance.Room].Doors, layoutData)); } // Add level info var levelInfo = rootGameObject.GetComponent <LevelInfo>(); if (levelInfo != null) { PostProcessUtils.Destroy(levelInfo); } levelInfo = rootGameObject.AddComponent <LevelInfo>(); levelInfo.RoomInstances = layoutData.Values.ToList(); return(new GeneratedLevel(layoutData, layout, rootGameObject)); }