UE5 Blueprintでタイルを並べるだけ

# 概要

Unreal Engine 初心者が Blueprint を触ってみた時の個人的な備忘録。

**実行したらタイルを動的に敷き詰めるようにする**

これだけ。

![2025-01-14_03h08_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/07d6aaa9-f200-dda5-9035-e57b4dcd4ff5.png)

今回と[次回](https://qiita.com/tukanpo/items/704ea3a179054a948ca0)の内容を含めたプロジェクト一式。
プレイヤーの作成と配置も含まれているが正直これを見た方が早い。

https://github.com/tukanpo/CM40/tree/v2

## 環境

UE 5.5.1

## 新規プロジェクトを作成する

何も入っていないプロジェクトから始める

- UE5 を起動して `ゲーム` タブから `ブランク` を選択
- プロジェクトの場所、プロジェクト名を入力
- 作成ボタンを押してプロジェクト作成

![2025-01-13_19h59_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/8f49f828-6307-ce37-903c-b15e7e1b4e7d.png)

# レベルを作成する

プロジェクトの作成直後は未保存のオープンワールドレベルが表示されている。
今回はこれを使わずに、もうちょいシンプルな内容のテンプレートで新規レベルを作成することにする。

## レベルの保存用フォルダを作成

コンテンツブラウザの `コンテンツ` フォルダ以下に `[プロジェクト名]` のフォルダを作成し、
さらにその下に `Maps` フォルダを作成する。

※ コンテンツ配下のトップに `[プロジェクト名]` のフォルダを作る理由は下記を参照。
今後作成するアセットの名称なども大体これに従って命名する。

https://github.com/akenatsu/ue4-style-guide/blob/master/README.jp.md#22-%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%9B%BA%E6%9C%89%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%81%AB%E3%81%AF%E3%83%88%E3%83%83%E3%83%97%E3%83%AC%E3%83%99%E3%83%AB%E3%81%AE%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%82%92%E4%BD%BF%E3%81%86%E3%81%93%E3%81%A8-

![2025-01-13_21h53_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/c92b111c-72a7-701d-35d2-cb373798852e.png)

## 基本テンプレートでレベルを新規作成

メニューの `ファイル` > `新規レベル` > `基本` で新規レベル作成。

`Ctrl` + `S` を押すと保存ウィンドウが表示されるので、先ほどの `Maps` フォルダ以下に名前を付けて保存 (名前は `TestMap` とした）

![2025-01-14_23h04_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/b91dbd91-331a-70d6-0e71-adfa4eabf6d7.png)

## デフォルトマップを変更

メニューの `編集` > `プロジェクト設定` を開く。

`プロジェクト` > `マップ&モード` の Default Maps 内にある `エディタのスタートアップマップ` と `ゲームのデフォルトマップ` に、先ほど作成した `TestMap` を指定する。

![2025-01-14_23h19_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/1c09eca1-b217-7ca4-408f-469f274db9bd.png)

### Floor を削除

要らないのでアウトライナーにある `Floor` は Delete で削除しておく。

![2025-01-16_10h18_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/291ac8fa-5f7a-88ac-3953-60802b6c772b.png)

# タイルを作成する

## タイルとなるメッシュを用意する

タイルは3Dオブジェクトで表現するのでメッシュを適当に用意する。

※ プロトタイプで使うような簡単な物ならエディタのモデリングモードでも作れるようだけど、使い方がよくわからんので今回は Blender でキューブを作成した。
![2025-01-15_00h13_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/b73669f9-cd70-6199-4f76-0bb448cbb945.png)

`SM_BoardTile.fbx`
![2025-01-15_00h10_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/abe4b3eb-5864-8d73-d2fa-96a2b350d5bb.png)

`Props` フォルダを作成して FBX を D&D でインポート。

インポート設定はデフォルトにしたが、オフセットのZ軸を -90 にしておいた方が良いかも。
今回は忘れてやってないけど、まだテクスチャを貼っていないのでどの方向を向いているかは関係ないのでどっちでもいい。

![2025-01-15_00h22_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/fdd5401b-38dc-b05c-3d30-0e9e464a424e.png)

## タイル用のアクタを作成する (BP_BoardTile)

※アクタはレベルに配置可能なオブジェクトの基本単位。

`[プロジェクト名]` のフォルダ以下に `Blueprints` フォルダを新たに作成。

フォルダ内の適当な箇所で右クリック、表示されたメニューで `ブループリント クラス` を選択。

![2025-01-15_00h03_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/21b27f56-892b-afbd-3fce-e93535dd2bf3.png)

`親クラスを選択` > `アクタ` を選択。

ブループリントが作成されるので、名前を `BP_BoardTile` と命名。

## スタティックメッシュコンポーネント追加

`BP_BoardTile` をダブルクリックで開く。

![2025-01-15_01h30_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/d206487b-fab9-cdd5-3097-52cedd504703.png)

左上にあるコンポーネントウィンドウの追加ボタンから `スタティックメッシュコンポーネント` を追加。

![2025-01-15_01h34_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/e5f546f8-131c-b084-4cee-cc6964e99417.png)

次に、画面右にある詳細ウィンドウでスタティックメッシュを先ほど追加した `SM_BoardTile` に変更。

![2025-01-15_01h36_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/99ccfea6-d748-b47f-51b3-953d66dca952.png)

最後に左上のコンパイルボタンを押してメッシュの設定は完了。

:::note warn
コンパイルしないと実行しても反映されないので注意。今後は特に明記しない。

![2025-01-15_01h41_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/9b252a59-280a-b738-6d0c-eac5f7a9f342.png)
:::

## 変数を追加

タイルは生成時に自身のグリッド座標を格納しておきたいので変数を１つ追加する。

### GridPos

画面左のマイブループリント ウィンドウで変数欄の横にある＋ボタンを押す。
新しい変数が追加されるので下記のように設定する。

- GridPos (Int Point)

Int Point は 2D 整数座標(x, y)を格納できる構造体。

![2025-01-16_07h45_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/8f9468d9-df4c-2351-0422-d27935ee579b.png)

# タイルを管理するボードを作成する (BP_GameBoard)

タイルを生成 / 管理する為のアクタである `BP_GameBoard` を新たに作成する。

## 変数を追加

### BoardTiles
- BoardTiles (`Map` <キー: `Int Point`, 値: `BP_BoardTile`>)

Map は BluePrint で使える連想配列。
グリッド座標である Int Point をキーとして全てのタイルを格納する。

先ほどと同じように変数を追加する。型は別ウィンドウで変更するのでなんでも良い。

![2025-01-16_08h40_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/7e93665b-70c5-d9a6-f451-1b9762dc88e7.png)

画面左の詳細ウィンドウで、変数の型を Map に変更する。

![2025-01-16_08h43_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/463ee438-39d5-241a-0f00-3902f66ea75d.png)

値を `BP_BoradTile` にして完了。

![2025-01-16_08h44_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/4b69b4e5-5995-1e53-05e2-e4fcf82c2f9c.png)

### TileSize
- TileSize (float)

タイルの実サイズを設定する変数。あとでタイルの生成位置を計算する為に使う。

![2025-01-16_08h50_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/7c896828-3505-87af-43a7-fc037b45e1e5.png)

変数を追加したら詳細ウィンドウでデフォルト値を設定しておく。
この値はタイルのモデルサイズ（縦横の幅 2.1m にしてあるので 210 にした）

![2025-01-16_08h52_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/c20bfe59-9c43-f7a2-f5a4-b521e51bf359.png)

## 関数を追加

### CalcTileLocation

さきほどの TileSize とグリッド座標を掛け合わせてタイルの配置位置を計算する為の関数を用意する。

今回は関数にインプット(引数)とアウトプット(戻り値)も詳細ウィンドウから追加。

![2025-01-19_03h21_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/b1a3ca8d-52e1-8380-27f0-1bae5778ea7e.png)

#### インプット

- TileSize (float)
- GridPos (IntPoint)

#### アウトプット

- Location (Vector)

#### Blueprint

![2025-01-19_03h19_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/85f9b912-42db-7d7c-fa43-b6a5306d5d51.png)

このノードは乗算 (Multiply)
![2025-01-16_09h12_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/e6326ae9-d4f1-1aae-cd58-5c16d80e9f13.png)

### GenerateTiles

#### ローカル変数

関数内でのみ使用可能なローカル変数を定義しておく。
ループ中に現在のグリッド座標を一時的に保持しておく為の変数。

![2025-01-16_09h15_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/ab6ca2be-cd4b-5077-5a9c-b97c36bad387.png)

- CurrentGridPos (Int Point)

#### インプット

- GirdSize (Int Point)

#### Blueprint

![2025-01-19_01h35_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/c3bd4793-08b6-2591-3ed6-fa069738860b.png)

(1). x, y の２重ループを回す
(2). インデックス (x,y) を引数として CalcTileLocation に渡しワールド座標の位置を計算
(3). ワールド座標を引数に SpawnActor でタイルを生成
(4). 生成したタイルを BoardTiles へ格納

# ゲームモードを作成する (GM_TestGame)

今度はブループリントクラス作成時にアクタではなくゲームモードを選んで作成する。

![2025-01-16_09h37_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/ce3c61ae-f6db-3ecd-9490-bfdc5c7341b6.png)

名前は `GM_TestGame`

## 変数を追加

GameBoard (BP_GameBoard)

## 関数を追加

### InitGameBoard

#### インプット

- GirdSize (Int Point)

#### Blueprint

![2025-01-16_09h47_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/b15a4b41-6c41-8d6c-3e33-c53d9972c0ad.png)

#### イベントグラフ

![2025-01-16_09h48_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/f8bdd4bb-d2ab-e039-4cdc-ea0f6ead9793.png)

InitGameBoard の引数には x:5, y:5 を指定して 5x5 のサイズでボードを作成する。

## ゲームモードをオーバーライドする

ワールドセッティングウィンドウ内のゲームモードオーバーライドを GM_TestGame に変更。

![2025-01-16_10h21_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/ec4b0bad-310f-8456-6769-1878d99f71f1.png)

## 実行する

今回設定した 5x5 で表示される（はず）

![2025-01-16_10h23_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18334/962035da-4f4d-bae8-93fa-d34ae94da107.png)

次回はこちら

https://qiita.com/tukanpo/items/704ea3a179054a948ca0

おわり