public void SetPreviewTilemap(Unity_Map map, Unity_Tile[,] newTiles) { int w = newTiles.GetLength(0); int h = newTiles.GetLength(1); if (w <= 0 || h <= 0) { ClearPreviewTilemap(); return; } int cellSize = LevelEditorData.Level.CellSize; Texture2D tex = new Texture2D(w * cellSize, h * cellSize); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { Unity_Tile newTile = newTiles[x, y]; Unity_TileTexture tile = map.GetTile(newTile, LevelEditorData.CurrentSettings); FillInTilePixels(tex, tile, newTile, x, y, cellSize, applyTexture: false); } } tex.filterMode = FilterMode.Point; tex.Apply(); tilemapPreview.sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0, 0), LevelEditorData.Level.PixelsPerUnit, 0, SpriteMeshType.FullRect); }
public void SetTileAtPos(int x, int y, Unity_Tile newTile, bool applyTexture = true) { var map = LevelEditorData.Level.Maps[LevelEditorData.CurrentMap]; if (y < 0 || y >= map.Height) { return; } if (x < 0 || x >= map.Width) { return; } // Update tile graphics for (int i = 0; i < CollisionTilemaps.Length; i++) { CollisionTilemaps[i].SetTile(new Vector3Int(x, y, 0), null); var type = LevelEditorData.Level.GetCollisionTypeGraphicFunc(newTile.Data.CollisionType); if (CurrentCollisionIcons.ContainsKey(type)) { CollisionTilemaps[i].SetTile(new Vector3Int(x, y, 0), CurrentCollisionIcons[type]); } } for (int i = 0; i < GraphicsTilemaps.Length; i++) { Texture2D tex = GraphicsTilemaps[i].sprite.texture; Unity_TileTexture tile = map.GetTile(newTile, LevelEditorData.CurrentSettings); int cellSize = LevelEditorData.Level.CellSize; FillInTilePixels(tex, tile, newTile, x, y, cellSize, applyTexture: applyTexture); } // Get the tile to set var destTile = map.MapTiles[y * map.Width + x]; // Update destination tile values destTile.Data.CollisionType = newTile.Data.CollisionType; destTile.PaletteIndex = newTile.PaletteIndex; destTile.Data.TileMapX = newTile.Data.TileMapX; destTile.Data.TileMapY = newTile.Data.TileMapY; destTile.Data.PC_Unk1 = newTile.Data.PC_Unk1; destTile.Data.PC_Unk2 = newTile.Data.PC_Unk2; // Get the correct transparency mode to set if available if (map.TileSetTransparencyModes != null) { destTile.Data.PC_TransparencyMode = map.TileSetTransparencyModes[(map.TileSetWidth * newTile.Data.TileMapY) + newTile.Data.TileMapX]; } }
private void FillInTilePixels(Texture2D tex, Unity_TileTexture tile, Unity_Tile t, int x, int y, int cellSize, bool applyTexture = false) { int texX = x * cellSize; int texY = y * cellSize; bool flipY = (t?.Data.VerticalFlip ?? false); bool flipX = (t?.Data.HorizontalFlip ?? false); if (tile?.texture == null) { tex.SetPixels(texX, texY, cellSize, cellSize, new Color[cellSize * cellSize]); } else { var tileTex = tile.texture; tex.SetPixels(texX, texY, cellSize, cellSize, tile.GetPixels(flipX, flipY)); } if (applyTexture) { tex.Apply(); } }
/// <summary> /// Gets the tile for the specific map tile /// </summary> /// <param name="mapTile">The map tile</param> /// <param name="settings">The game settings</param> /// <returns>The tile</returns> public Unity_TileTexture GetTile(Unity_Tile mapTile, GameSettings settings, int?tileIndexOverride = null) { // Get the tile index int tileIndex; if (tileIndexOverride.HasValue) { tileIndex = (TileSetWidth * tileIndexOverride.Value) + mapTile.Data.TileMapX; } else { tileIndex = (TileSetWidth * mapTile.Data.TileMapY) + mapTile.Data.TileMapX; } // Get the tile array var tiles = TileSet[mapTile.PaletteIndex - 1].Tiles; // Check if it's out of bounds if (tileIndex >= tiles.Length) { // If it's out of bounds and the level is Jungle 27 in PS1 EDU, hard-code to 509, which is what the game uses there if (settings.EngineVersion == EngineVersion.R1_PS1_Edu && settings.R1_World == R1_World.Jungle && settings.Level == 27) { tileIndex = 509; } // Hacky fix for RRR else if (settings.EngineVersion == EngineVersion.GBARRR && settings.Level == 25) { tileIndex = 4082; } else { Debug.LogWarning($"Out of bounds tile with index {tileIndex} in {settings.GameModeSelection} - {settings.World}{settings.Level}"); tileIndex = 0; } } // Return the tile return(tiles[tileIndex]); }
// Get one common tile at given position public Unity_Tile GetTileAtPos(int x, int y) { if (LevelEditorData.Level == null) { return(null); } var map = LevelEditorData.Level.Maps[LevelEditorData.CurrentMap]; if (focusedOnTemplate) { // Get the 1-dimensional graphic tile index var graphicIndex1D = (y * LevelEditorData.Level.CellSize) + x; if (graphicIndex1D > map.TileSet[0].Tiles.Length - 1) { graphicIndex1D = 0; } Unity_Tile t = new Unity_Tile(new MapTile()); t.Data.TileMapY = (ushort)Mathf.FloorToInt(graphicIndex1D / (float)map.TileSetWidth); t.Data.TileMapX = (ushort)(graphicIndex1D - (map.TileSetWidth * t.Data.TileMapY)); return(t); } var shallow_tile = map.GetMapTile(x, y); Unity_Tile u; if (shallow_tile == null) { u = new Unity_Tile(new MapTile()); } else { u = shallow_tile.CloneObj(); } return(u); }
public Unity_AnimatedTile.Instance GetAnimatedTile(Unity_Tile mapTile, GameSettings settings) { // Get the tile index var tileIndex = (TileSetWidth * mapTile.Data.TileMapY) + mapTile.Data.TileMapX; var tileset = TileSet[mapTile.PaletteIndex - 1]; if (tileset.AnimatedTiles != null) { foreach (var at in tileset.AnimatedTiles) { if (at.TileIndices?.Length > 0 && at.TileIndices[0] == tileIndex) { //int index = Array.IndexOf(at.TileIndices, tileIndex); int index = 0; if (index >= 0) { return(new Unity_AnimatedTile.Instance(at, index)); } } } return(null); } return(null); }
void Update() { //Take care of showing and hiding tiles, types and events -layers if (Settings.ShowTiles != layerTiles.activeSelf) { layerTiles.SetActive(!layerTiles.activeSelf); ChangeVisibButton(0); } if (Settings.ShowCollision != layerTypes.activeSelf) { layerTypes.SetActive(!layerTypes.activeSelf); ChangeVisibButton(1); } if (lvlTilemapController?.IsometricCollision != null) { if (Settings.ShowCollision != lvlTilemapController.IsometricCollision.activeSelf) { lvlTilemapController.IsometricCollision.SetActive(Settings.ShowCollision); } } if (Settings.ShowObjects != layerEvents.activeSelf) { layerEvents.SetActive(!layerEvents.activeSelf); ChangeVisibButton(2); } ChangeVisibButton(3); if (Controller.LoadState != Controller.State.Finished || LevelEditorData.Level == null) { return; } var map = LevelEditorData.Level.Maps[LevelEditorData.CurrentMap]; //Tile editing if (currentMode == EditMode.Tiles || currentMode == EditMode.Collisions) { // Get the tile under the mouse Vector3 mousePositionTile = lvlController.controllerTilemap.MouseToTileCoords(mousePosition); Vector2Int mouseTileInt = lvlController.controllerTilemap.MouseToTileInt(mousePosition); mouseTile = lvlController.controllerTilemap.GetTileAtPos(mouseTileInt.x, mouseTileInt.y); // =============== SELECTION SQUARE =============== // Escape clears selection info if (GetKeyDown(KeyCode.Escape)) { ClearSelection(); } // Left click begins drag and assigns the starting corner of the selection square if (!dragging && mouseTile != null) { if (!EventSystem.current.IsPointerOverGameObject()) { if (GetMouseButtonDown(0)) { tileSelectSquare.SetStartCorner(mouseTileInt.x, mouseTileInt.y); dragging = true; selecting = true; //Clear old preview tilemap if (currentMode == EditMode.Tiles) { lvlTilemapController.ClearPreviewTilemap(); } } else if (GetMouseButtonDown(1)) { tileSelectSquare.SetStartCorner(mouseTileInt.x, mouseTileInt.y); dragging = true; selecting = false; } } } if (dragging) { // During drag, set the end corner var endX = Mathf.Clamp(mouseTileInt.x, 0, (lvlTilemapController.camMaxX - 1)); var endY = Mathf.Clamp(mouseTileInt.y, 0, (lvlTilemapController.camMaxY - 1)); if (selecting) { tileSelectSquare.color = colorSelect; tileSelectSquare.SetEndCorner(endX, endY); } else { tileSelectSquare.color = colorNew; tileSelectSquare.SetEndCorner(endX, endY); if (currentMode == EditMode.Tiles) { // Change preview position lvlTilemapController.tilemapPreview.transform.position = new Vector3(tileSelectSquare.XStart * lvlTilemapController.CellSizeInUnits, -(tileSelectSquare.YStart * lvlTilemapController.CellSizeInUnits)); // Expand the preview tiles if (selection != null) { lvlTilemapController.SetPreviewTilemap(map, selection); } } } // Auto scroll if dragging near the screen margin and not manually moving the camera if (GetMouseButton(1)) { float scr = Camera.main.orthographicSize * cam.friction * autoScrollSpeed * Time.deltaTime; bool inMarginLeft = mousePosition.x < autoScrollMargin; bool inMarginRight = mousePosition.x > Screen.width - autoScrollMargin; bool inMarginTop = mousePosition.y < autoScrollMargin; bool inMarginBottom = mousePosition.y > Screen.height - autoScrollMargin; bool inMargin = inMarginLeft || inMarginRight || inMarginTop || inMarginBottom; if (inMarginLeft) { cam.vel.x -= scr; } if (inMarginRight) { cam.vel.x += scr; } if (inMarginTop) { cam.vel.y -= scr; } if (inMarginBottom) { cam.vel.y += scr; } if (inMargin) { scrolling = true; } } } else { scrolling = false; //Move preview with mouse if not dragging lvlTilemapController.tilemapPreview.transform.position = mousePositionTile; } // Reset camera friction from the drag's override if moved manually if (GetMouseButtonDown(1)) { cam.friction = cam.fricStart; } if (dragging) { if (currentMode == EditMode.Tiles) { // If dragging and selecting mouse up, record the selection if (selecting && !GetMouseButton(0)) { dragging = false; // Create array for selected area selection = new Unity_Tile[(int)(tileSelectSquare.XEnd - tileSelectSquare.XStart) + 1, (int)(tileSelectSquare.YEnd - tileSelectSquare.YStart) + 1]; int xi = 0; int yi = 0; // Save the selected area //print(tileSelectSquare.XStart + " - " + tileSelectSquare.XEnd + " - " + tileSelectSquare.YStart + " - " + tileSelectSquare.YEnd); for (int y = (int)tileSelectSquare.YStart; y <= tileSelectSquare.YEnd; y++) { for (int x = (int)tileSelectSquare.XStart; x <= tileSelectSquare.XEnd; x++) { var t = lvlController.controllerTilemap.GetTileAtPos(x, y); selection[xi, yi] = t; xi++; } xi = 0; yi++; } if (currentMode == EditMode.Tiles) { lvlTilemapController.SetPreviewTilemap(map, selection); } } // If dragging and painting mouse up, set the selection if (!selecting && GetMouseButtonUp(1)) { dragging = false; if (selection != null) { if (!lvlTilemapController.focusedOnTemplate) { int xi = 0; int yi = 0; //"Paste" the selection for (int y = (int)tileSelectSquare.YStart; y <= tileSelectSquare.YEnd; y++) { for (int x = (int)tileSelectSquare.XStart; x <= tileSelectSquare.XEnd; x++) { var t = map.GetMapTile(x, y); TempPrevTileHistory.Add(new Ray1MapEditorHistoryTile(t.CloneObj(), x, y)); var selectionTile = selection[xi, yi]; lvlController.controllerTilemap.SetTileAtPos(x, y, selectionTile); t.HasPendingEdits = true; TempTileHistory.Add(new Ray1MapEditorHistoryTile(selectionTile.CloneObj(), x, y)); xi++; if (xi >= selection.GetLength(0)) { xi = 0; } } xi = 0; yi++; if (yi >= selection.GetLength(1)) { yi = 0; } } } // Cut the preview back to the original size since it's been expanded if (currentMode == EditMode.Tiles) { lvlTilemapController.SetPreviewTilemap(map, selection); } } } } else if (currentMode == EditMode.Collisions) { //Fill with selected type if (selecting && !GetMouseButton(0)) { dragging = false; //Paste the current type for (int y = (int)tileSelectSquare.YStart; y <= tileSelectSquare.YEnd; y++) { for (int x = (int)tileSelectSquare.XStart; x <= tileSelectSquare.XEnd; x++) { var t = map.GetMapTile(x, y); TempPrevTileHistory.Add(new Ray1MapEditorHistoryTile(t.CloneObj(), x, y)); var tile = lvlController.controllerTilemap.SetTypeAtPos(x, y, (ushort)currentType); t.HasPendingEdits = true; TempTileHistory.Add(new Ray1MapEditorHistoryTile(tile.CloneObj(), x, y)); } } } //Fill with empty if (!selecting && GetMouseButtonUp(1)) { dragging = false; for (int y = (int)tileSelectSquare.YStart; y <= tileSelectSquare.YEnd; y++) { for (int x = (int)tileSelectSquare.XStart; x <= tileSelectSquare.XEnd; x++) { var t = map.GetMapTile(x, y); TempPrevTileHistory.Add(new Ray1MapEditorHistoryTile(t.CloneObj(), x, y)); var tile = lvlController.controllerTilemap.SetTypeAtPos(x, y, 0); t.HasPendingEdits = true; TempTileHistory.Add(new Ray1MapEditorHistoryTile(tile.CloneObj(), x, y)); } } } } } // Stamp selection with ctrl+v if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.V) && !dragging) { if (selection != null && !lvlTilemapController.focusedOnTemplate) { int xi = 0; int yi = 0; int w = LevelEditorData.Level.Maps[LevelEditorData.CurrentMap].Width; int h = LevelEditorData.Level.Maps[LevelEditorData.CurrentMap].Height; int my = mouseTileInt.y; int mx = mouseTileInt.x; // "Paste" the selection for (int y = my; y <= my + selection.GetLength(1) - 1; y++) { for (int x = mx; x <= mx + selection.GetLength(0) - 1; x++) { if (x >= 0 && y >= 0 && x < w && y < h) { var t = map.GetMapTile(x, y); TempPrevTileHistory.Add(new Ray1MapEditorHistoryTile(t.CloneObj(), x, y)); //lvlController.controllerTilemap.SetTileAtPos(x, y, selection[xi, yi]); t.HasPendingEdits = true; TempTileHistory.Add(new Ray1MapEditorHistoryTile(selection[xi, yi].CloneObj(), x, y)); } xi++; } xi = 0; yi++; } lvlController.controllerTilemap.SetTileBlockAtPos(mx, my, selection.GetLength(0), selection.GetLength(1), selection); } } // Check if the editor actions should be undone/redone if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.Z)) { if (Input.GetKey(KeyCode.LeftShift)) { // Redo Controller.obj.levelController.History.Redo(); } else { // Undo Controller.obj.levelController.History.Undo(); } } // Add to history if any tiles were added if (TempTileHistory.Any()) { // Add to history Controller.obj.levelController.History.AddToHistory(new EditorHistoryEntry <Ray1MapEditorHistoryItem>(new Ray1MapEditorHistoryItem(TempPrevTileHistory.ToArray()), new Ray1MapEditorHistoryItem(TempTileHistory.ToArray()))); // Clear temp lists TempTileHistory.Clear(); TempPrevTileHistory.Clear(); } } }