🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

2375閲覧

Tilemapを二次元配列に落とし込む方法

UltraSuperMikan

総合スコア20

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

1クリップ

投稿2019/10/25 00:10

編集2019/10/25 00:25

前提・実現したいこと

Tilemap上にいるキャラクター群の状態を、二次元配列などで管理したい。
(キャラクターは、タイルマップ上を1マスずつ4方向にしか動けないようにしている)

発生している問題・エラーメッセージ

まず、tilemap.sizeで二次元配列を生成する。
これに、マップ上のキャラクターすべての状態を代入しようとした。

キャラクターのpositionをcellSizeなどを利用して、セル座標(?)として算出する。
これは負の値が出てくる事があるので、そのままでは配列のインデックスに使えない。
しかし、マップの形状もXY軸対称とも限らないので、セル座標→二次元配列のインデックス[x,y]に換算できない。

以下、編集中のスクリプトの問題箇所

c#

1 // class member 2 private static bool[,] distributionMap; 3 // instance only 4 private PlayerSquareMove squareMove = null; 5 6 // Start is called before the first frame update 7 void Start() 8 { 9 // static once-process 10 if (distributionMap == null) 11 { 12 distributionMap = new bool[ 13 PlayerSquareMove.GetCollisionTilemap().size.x, 14 PlayerSquareMove.GetCollisionTilemap().size.y]; 15 16 for (int i = 0; i < distributionMap.GetLength(0); i++) 17 for (int j = 0; j < distributionMap.GetLength(1); j++) 18 distributionMap[i, j] = false; 19 } 20 21 // instance only 22 squareMove = GetComponent<PlayerSquareMove>(); 23 var cellPos = squareMove.GetCellPosition(); // Vector3Int型 24 if (distributionMap[cellPos.x, cellPos.y]) // ★値によっては、ここでエラー。 25 { 26 Debug.LogError("duplicated"); 27 Destroy(gameObject); 28 } 29 }

補足情報(FW/ツールのバージョンなど)

Unity 2018.4.11

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

まず考えられるのは専用のクラスを作っちゃうとかですかね?
もっと他にも良いやり方ありそうですが一応一案として。

C#

1class MapData { //名前は適当 2 public int x; 3 public int y; 4 public bool flag; 5} 6 7private static MapData[] distributionMap; 8// あとは検索用のメソッド作る

投稿2019/10/25 01:18

sakura_hana

総合スコア11427

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

UltraSuperMikan

2019/10/25 01:47

回答ありがとうございます。 盲点でした、頭が回っていない……。 今日~明日中に妙案が浮かばなければ、その案を採用させていただきます。 しかし、tilemap全体の幅高さが取得可能なのに、四隅の座標を拾えないのが気がかりです。 マス目を数えて、オフセットを手動入力する他ないのでしょうか……。
guest

0

BA後ですが、思いついてしまったので……。すみません。

Tilemap上の追加情報を、どうしても二次元配列で扱いたかったので、少し妙な方法を考えてみました。
(数学が苦手なので、自前データを作成した場合、データ検索で異様に重くなってしまい、毎フレーム実行することが困難であったため……。)


イメージ説明
方法はとても単純です。
自分で編集したTilemap上の左下に、マーカー用GameObjectを配置し、スクリプトでその座標を読み取り、負の値が出た場合は、二次元配列のxyインデックスのオフセット値として保持・利用します。

c#

1// 編集中クラス内 2static Vector2Int min_MapCellPosition; 3 4void Awake() 5{ 6 if(min_MapCellPosition == new Vector2()) 7 { 8 var min_marker = GameObject.Find("min_MapCell"); 9 // tilemapのアンカーがBottomLeftなので, -0.5する. 10 min_MapCellPosition.x = (int)(min_marker.transform.position.x - 0.5f); 11 min_MapCellPosition.y = (int)(min_marker.transform.position.y - 0.5f); 12 } 13}

誤った位置にマーカーをおいた場合は、計算結果にズレが生じるか、アウトオブレンジを吐くと思うので、すぐに気付けるはず…………問題ないはず…………。

投稿2019/10/27 00:42

編集2019/10/27 01:17
UltraSuperMikan

総合スコア20

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問