Unityのバージョン:2018.3.5f1
ダンジョン探索型のゲームって、だいたい端っこにダンジョンのミニマップがついてますよね。自分の位置とか一度発見した宝箱の位置とかがわかるやつ。
今回はUnity2017で実装されたTilemapを用いて作成したステージに対応した、ミニマップの作成法を考えてみました。
ただ、AssetStoreには既に高品質のミニマップ機能がいくつもあるので、無理に自作する必要はないと思います。
自分はAssetStoreのツールがTileMapに対応しているのかチェックするのが面倒だった(英語から逃げた)のと、ちょっと調べただけでも参考になる記事がいくつもあったから試してみただけです。
Gridオブジェクトの下に
の3つのTileMapがあります。
Colliderが設定されているのは「Wall」と「Item」です。
まずは右下にマップ用の画面を表示します。
1.空のオブジェクト「MiniMap」を作成し、その下に新しくCameraを作成
2.Cameraの設定を以下のように変更
今はマップカメラに映っている内容が、Main Cameraに映っている内容と同じです。
これを壁と地面が単色で塗られた画像に変えていきます。
まずは、Tilemapの情報からマップ用のテクスチャを作成します。
1.MiniMap.csを作成し、MiniMapオブジェクトにコンポーネントを追加する
2.MiniMap.csに以下を記述
using UnityEngine;
using UnityEngine.Tilemaps;
using UnityEngine.UI;
public class MiniMap : MonoBehaviour
{
[SerializeField] Transform _grid;
[SerializeField] Image _image;
// マップの色
[SerializeField] Color _wallColor;
[SerializeField] Color _groundColor;
[SerializeField] Color _noneColor;
// マップ用テクスチャ
Texture2D _texture;
void Start()
{
Tilemap groundTilemap = _grid.Find("Ground").GetComponent<Tilemap>();
Tilemap wallTilemap = _grid.Find("Wall").GetComponent<Tilemap>();
// テクスチャ作成
Vector3Int size = wallTilemap.size;
_texture = new Texture2D(size.x, size.y, TextureFormat.ARGB32, false);
// こうしないと、画像がぼやける
_texture.filterMode = FilterMode.Point;
Vector3Int origin = wallTilemap.origin;
// テクスチャ座標ごとの色を求める
for (int y = 0; y < size.y; ++y)
{
for (int x = 0; x < size.x; ++x)
{
// Tilemapのグリッド座標
Vector3Int cellPos = new Vector3Int(origin.x + x, origin.y + y, 0);
// 壁タイルが存在する
if (wallTilemap.GetTile(cellPos) != null)
{
_texture.SetPixel(x, y, _wallColor);
}
// 地面タイルが存在する
else if (groundTilemap.GetTile(cellPos) != null)
{
_texture.SetPixel(x, y, _groundColor);
}
// なにもない場所
else
{
_texture.SetPixel(x, y, _noneColor);
}
}
}
// テクスチャ確定
_texture.Apply();
// テクスチャをImageに適用
_image.rectTransform.sizeDelta = new Vector2(size.x, size.y);
_image.sprite = Sprite.Create(_texture, new Rect(0, 0, size.x, size.y), Vector2.zero);
// _imageをGridの中心に移動
Vector2 leftDownWorldPos = wallTilemap.CellToWorld(origin);
Vector2 rightUpWorldPos = wallTilemap.CellToWorld(origin + size);
_image.transform.position = (leftDownWorldPos + rightUpWorldPos) * 0.5f;
}
private void OnDestroy()
{
Destroy(_texture);
}
}
3.MiniMapオブジェクトの下に「Canvas」を、さらに下に「Image」を作成する
4.MiniMapオブジェクトのMiniMapの設定を以下のように変更
MiniMap.csでやっていることは
Tilemap groundTilemap = _grid.Find("Ground").GetComponent<Tilemap>();
Tilemap wallTilemap = _grid.Find("Wall").GetComponent<Tilemap>();
// テクスチャ作成
Vector3Int size = wallTilemap.size;
_texture = new Texture2D(size.x, size.y, TextureFormat.ARGB32, false);
// こうしないと、画像がぼやける
_texture.filterMode = FilterMode.Point;
FilterModeをPointにしないとこんな感じになります。
3.Tilemapのタイルの有無から、テクスチャ座標の色を決定する
Vector3Int origin = wallTilemap.origin;
// テクスチャ座標ごとの色を求める
for (int y = 0; y < size.y; ++y)
{
for (int x = 0; x < size.x; ++x)
{
// Tilemapのグリッド座標
Vector3Int cellPos = new Vector3Int(origin.x + x, origin.y + y, 0);
// 壁タイルが存在する
if (wallTilemap.GetTile(cellPos) != null)
{
_texture.SetPixel(x, y, _wallColor);
}
// 地面タイルが存在する
else if (groundTilemap.GetTile(cellPos) != null)
{
_texture.SetPixel(x, y, _groundColor);
}
// なにもない場所
else
{
_texture.SetPixel(x, y, _noneColor);
}
}
}
4.ImageをTextureと同じサイズに変更し、SpriteにTextureを適用する。その後、Imageの中心をステージの中心に合わせる
// テクスチャ確定
_texture.Apply();
// テクスチャをImageに適用
_image.rectTransform.sizeDelta = new Vector2(size.x, size.y);
_image.sprite = Sprite.Create(_texture, new Rect(0, 0, size.x, size.y), Vector2.zero);
// _imageをGridの中心に移動
Vector2 leftDownWorldPos = wallTilemap.CellToWorld(origin);
Vector2 rightUpWorldPos = wallTilemap.CellToWorld(origin + size);
_image.transform.position = (leftDownWorldPos + rightUpWorldPos) * 0.5f;
このままだと肝心のステージの画像が隠されてしまうので、マップカメラにはマップ画像だけを表示し、逆にMain Cameraではマップ画像を非表示にします。
1. Edit>Project Settings>Tags and Layers でLayersのウインドウを開き、「MiniMap」を追加する
2.「MiniMap>Canvas」のLayerを「MiniMap」に変更する
3.「MiniMap>Camera」の「Culling Mask」を「MiniMap」に変更する
4.「Main Camera」の「Culling Mask」を「MiniMap以外」を選択状態に変更する
だいぶそれっぽい感じになってきました。
疲れたので、残りはまた今度書きます。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント