ãUnityã2Dã¿ã¤ã«ããã18 2ãã¹ã§1ãªãã¸ã§ã¯ãã®Tileãå転ããã
Unity 2021.1.0f1 Personal(2021å¹´3æ)
ååã®ç¶ãã§ãï¼
ååã¯2ãã¹ã§1ãªãã¸ã§ã¯ãã®Tileãæ´ãã§ç§»åããã¦é
ç½®ãããã¨ããã¾ã§é²ãã¾ããã
ä»åã¯ãã¡ãã®ãªãã¸ã§ã¯ãã移åããã¦ããæã«ã¹ãã¼ã¹ãã¼ãæ¼ãã¨ããªãã¸ã§ã¯ããå·¦å³å転ããæ©è½ãå®è£
ãã¦ããã¾ãã
MoveTileControllerã®æ´æ°
Tilemapãªã©ã®è¨å®ãååçµäºæã®ç¶æ
ã¾ã§é²ãã¦ããã¦ä¸ããã
æºåãæ´ãã¾ãããååä½æããMoveTileController.csãæ´æ°ãã¾ãã
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Tilemaps; public class MoveTileController : MonoBehaviour { [SerializeField] TileScriptableObject tileSO; [SerializeField] Tilemap defaultTilemap; [SerializeField] Tilemap moveTilemap; private Vector3Int deployCheckPos; private PlacedTiles selectTile; private List<PlacedTiles> placedTiles = new List<PlacedTiles>(); private void Start() { SetFurniture("tansu", 0, 0); SetFurniture("table", 2, 3); } private void SetFurniture(string name, int x, int y) { var tileStore = tileSO.tileDataList.Single(t => t.name == name); for (int i = 0; i < tileStore.tiles.Length; i++) { defaultTilemap.SetTile(new Vector3Int(x, y - i, 0), tileStore.tiles[i]); } placedTiles.Add(new PlacedTiles(tileStore, false, x, y)); } private void Update() { if (Input.GetMouseButton(0) && selectTile != null) { MoveTile(); } else if (Input.GetMouseButtonUp(0)) { if (selectTile == null) { SelectTile(); } else { DeployTile(); } } if (Input.GetKeyDown(KeyCode.Space) && selectTile != null) { selectTile.xFlip = !selectTile.xFlip; UpdateTile(0, 0); } } private void SelectTile() { // Cellä½ç½®åå¾ var mousePos = Input.mousePosition; mousePos.z = 10f; var cellPos = defaultTilemap.WorldToCell(Camera.main.ScreenToWorldPoint(mousePos)); // å®¶å ·ãç¡ããã°çµäº if (!defaultTilemap.HasTile(cellPos)) return; // å®¶å ·ãä¿å for (int i = 0; i < placedTiles.Count; i++) { for (int j = 0; j < placedTiles[i].tileBundle.Count; j++) { if (placedTiles[i].tileBundle[j].x == cellPos.x && placedTiles[i].tileBundle[j].y == cellPos.y) { selectTile = placedTiles[i]; break; } } if (selectTile != null) break; } // é¸æTileãMoveTilemapã¸ç§»å for (int i = 0; i < selectTile.tileBundle.Count; i++) { var pos = new Vector3Int(selectTile.tileBundle[i].x, selectTile.tileBundle[i].y, 0); moveTilemap.SetTile(pos, selectTile.tileBundle[i].tile); UpdateTileXFlip(moveTilemap, pos); defaultTilemap.SetTile(pos, null); } deployCheckPos = cellPos; } private void MoveTile() { // 移åå ãåå¾ var mousePos = Input.mousePosition; mousePos.z = 10f; Vector3Int nextPos = defaultTilemap.WorldToCell(Camera.main.ScreenToWorldPoint(mousePos)); // å®¶å ·ã®ä¸å¿ç¹ãã移åãã¦ããªããã°çµäº if (selectTile.GetBasisPoint() == nextPos) return; // Tileä½ç½®ãå¤æ´ UpdateTile(selectTile.GetBasisPoint().x - nextPos.x, selectTile.GetBasisPoint().y - nextPos.y); deployCheckPos = selectTile.GetBasisPoint() + Vector3Int.one; } private void DeployTile() { // å®¶å ·ä¸å¿ä½ç½®ã¨ãã§ãã¯ãã¤ã³ããéã£ããå¤ãæ´æ°ãã¦çµäº if (selectTile.GetBasisPoint() != deployCheckPos) { deployCheckPos = selectTile.GetBasisPoint(); return; } // moveTilemapããdefaultTilemapã¸Tileã移å selectTile.tileBundle.ForEach(tb => { var pos = new Vector3Int(tb.x, tb.y, 0); moveTilemap.SetTile(pos, null); defaultTilemap.SetTile(pos, tb.tile); UpdateTileXFlip(defaultTilemap, pos); }); selectTile = null; } private void UpdateTile(int diffX, int diffY) { // æ´æ°åTileãæ¶ã selectTile.tileBundle.ForEach(tb => moveTilemap.SetTile(new Vector3Int(tb.x, tb.y, 0), null)); // Tileæ å ±ã®æ´æ° int x = selectTile.tileBundle[0].x - diffX; int y = selectTile.tileBundle[0].y - diffY; selectTile.UpdateTilePos(x, y); // æ´æ°å¾Tileãé ç½® selectTile.tileBundle.ForEach(tb => { var pos = new Vector3Int(tb.x, tb.y, 0); moveTilemap.SetTile(pos, tb.tile); UpdateTileXFlip(moveTilemap, pos); }); } private void UpdateTileXFlip(Tilemap tilemap, Vector3Int pos) { if (selectTile.xFlip) { tilemap.SetTransformMatrix(pos, Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0.0f, 180.0f, 0.0f), Vector3.one)); } else { tilemap.SetTransformMatrix(pos, Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0.0f, 0.0f, 0.0f), Vector3.one)); } } public class PlacedTiles { public bool xFlip; public List<TileBundle> tileBundle = new List<TileBundle>(); public PlacedTiles(TileStore tileStore, bool xFlip, int x, int y) { this.xFlip = xFlip; for (int i = 0; i < tileStore.tiles.Length; i++) { this.tileBundle.Add(new TileBundle(tileStore.tiles[i], 0, 0)); } UpdateTilePos(x, y); } public void UpdateTilePos(int x, int y) { // xFlipã«ãã£ã¦é ç½®ãå¤ãã for (int i = 0; i < tileBundle.Count; i++) { tileBundle[i].x = xFlip ? x-i : x; tileBundle[i].y = xFlip ? y : y-i; } } public Vector3Int GetBasisPoint() { return new Vector3Int(tileBundle[0].x, tileBundle[0].y, 0); } public class TileBundle { public Tile tile; public int x; public int y; public TileBundle(Tile tile, int x, int y) { this.tile = tile; this.x = x; this.y = y; } } } }
MoveTileController.cs
PlacedTilesã¯ã©ã¹ã®UpdateTilePosã¡ã½ãã
PlacedTilesã¯ã©ã¹ã«xFlipã¨ããboolåå¤æ°ã追å ãã¾ããã
å転ãããæã«trueã平常æã«falseã¨ãªãã¾ãã
xFlipã¯UpdateTilePosã¡ã½ããå
ã§ä½¿ãããtrue(å転)ã®å ´åã¯x軸æ¹åã«Tileããºã©ãã¦ä¸¦ã¹ãfalse(é常)ã®å ´åã¯y軸æ¹åã«Tileããºã©ãã¦ä¸¦ã¹ã¾ãã
true(å転)ã®å ´åã¯xã1ãã¤ãã¤ãã¹ãã¦ä¸¦ã¹ã
false(é常)ã®å ´åã¯yã1ãã¤ãã¤ãã¹ãã¦ä¸¦ã¹ã
UpdateTileXFlipã¡ã½ãã
UpdateTileXFlipã¡ã½ããå
ã§Tileã®è§åº¦ãå¤æ´ãå転ãå®ç¾ããã¦ãã¾ãã
Tilemap.SetTransformMatrixã¡ã½ããã®ç¬¬ä¸å¼æ°ã§æå®ããä½ç½®ã®Tileãã第äºå¼æ°ã§æå®ããMatrix4x4ã®ç¶æ
ã«å¤æ´ãã¾ãã
Matrix4x4.TRSã¡ã½ããã§translation(ä½ç½®), rotation(è§åº¦), scaling(大ãã)ãå¤æ´ã§ãã¾ããä»åã¯rotationã®Yã®å¤ãå¤æ´ãã¦Tileãå転ããã¦ãã¾ãã
deployCheckPosï¼
Tileã®å転ã¨ã¯ç´æ¥é¢ä¿ããã¾ããããdeployCheckPosã¨ããå¤æ°ã追å ãã¾ããã
ããã«ãã家å
·ã®é
ç½®å
ã¾ã§ç§»åãããã¨ã«ããä¸åº¦åãå ´æãã¯ãªãã¯ãããã¨ã§ãDeployTileã¡ã½ãããå®è¡ãããããã«ãªãã¾ããã
çµæ
ããã§ã¯çµæãè¦ã¦ããã¾ãã
ç¡äºTileãæ´ãã§ç§»åããéä¸ã§å®¶å ·ãå転ãããã¨ãã§ãã¾ããã
ä»åã¯ä»¥ä¸ã¨ãªãã¾ãã
ãããã¨ããããã¾ãããã