
「いつかRPGを作ってみたい!」と思ったことがある人は多いのではないでしょうか?ただ、フィールドや町やイベントまで全部作ろうとすると、とんでもない量になってしまいます・・・。そこでこのシリーズでは、フィールドを歩く部分は作らずに、RPGの一番の楽しさであるコマンドバトルと育成に集中して、遊べるRPGを最初から最後まで作っていきます。今回は1回目として、プロジェクトを作って、4人の仲間が待つバトル画面のレイアウトを作ってみたいと思います!
- シリーズの目次:ターン制RPGの作り方
今回作るもの
- Universal 2Dでプロジェクトを作り、フォルダとシーンを用意する
- キャラクター・敵・背景の絵と、日本語のフォントを取り込む
- Canvasを「カメラに映す」設定にして、画面を場所ごとに分ける
- Stage:味方と敵が並ぶ場所(横から見た「サイドビュー」)
- MessageWindow:上のメッセージ
- CommandWindow:左下のコマンド
- StatusWindow:右下の味方のHP・MP
- 3人の仲間を並べて、その場でぷるぷる弾ませる
作るスクリプトは1つです。
| スクリプト | 役割 | 付ける場所 |
|---|---|---|
| IdleBounce | 待機のコマを切り替えて、その場で弾ませる | 3人の仲間 |
スライム今回の主人公はスライムちゃんと、フェアリー・キョンシー・メドゥーサの4人です!バトルには3人で出て、残りの1人とは図書館のロビーで入れ替えられるようにする予定です
プロジェクトを作ろう
- Unity Hubで新しいプロジェクトを作る
- エディターバージョン:Unity 6.3 LTS(記事作成時点では6000.3.22f1で確認しています)
- テンプレート:Universal 2D
- プロジェクト名:TurnBasedRpg(好きな名前でOK)
テンプレートの違いは1-2 プロジェクトを作る時のテンプレート選択で紹介しています。
プロジェクトが開いたら、先にフォルダとシーンを整えておきます。
- ProjectウインドのAssetsで右クリック>Create>Folderで「TurnBasedRpg」を作る
- 自分で作ったものは全部この中に入れるので、テンプレートに最初から入っているものと混ざりません
- その中に、Scripts・Sprites・Prefabs・Data・Effects・Audio・Fonts・Scenes の8つのフォルダを作る
- Assets>Scenes>SampleSceneをBattleにリネームして、TurnBasedRpg>Scenesに移動する


最後に、Gameビューの画面サイズを決めます。このシリーズはPCで遊ぶ横画面のゲームとして作ります。
- Gameビューの左上の解像度のドロップダウンを開き、一番下の+を押す
- Label:Full HD、Type:Fixed Resolution、Width & Height:1920・1080
- 作ったFull HD (1920×1080)を選ぶ
素材を取り込もう
シリーズで使う素材は、下のリンクからダウンロードしてください。全27回で使う素材(仲間4人・敵・背景・アイコン・音など)が、すべて入っています。
- TurnBasedRpgAssets.zip(約29MB)
取り込み方は2つあります。
- かんたん:zipの中の
TurnBasedRpgAssets.unitypackageをダブルクリック(またはAssets>Import Package>Custom Package…)- 取り込みの設定が入った状態で入るので、次の「絵の設定」は読むだけでOKです
- 自分で入れる:zipの中の
TurnBasedRpgフォルダを、UnityのAssetsにドラッグ&ドロップ- この場合は、次の設定を自分で合わせてください
素材は自由に使ってOKです(クレジット不要。作ったゲームの公開・販売にも使えます)。素材そのものの再配布はご遠慮ください。
入っている絵
| フォルダ | 中身 |
|---|---|
| Sprites/Characters | スライムちゃん・フェアリー・キョンシー・メドゥーサ(右向きのポーズと、正面のポーズ。200×200) |
| Sprites/Enemies | 地下1階の敵(こぼれたインク・紙ひこうき・本の虫) |
| Sprites/Backgrounds | 地下1階の書庫 |
| Sprites/UI | ウインドの枠、白い四角 |
4人の絵は、同じポーズが同じ番号になっているので、ファイル名の頭にキャラクターの名前を付けてあります(slime_walk_61.png、fairy_walk_61.pngなど)。名前が同じだと、Inspectorで絵を選ぶときにどれがだれだか分からなくなるためです。


絵の設定
- Spritesフォルダの中の画像を全部選ぶ(各フォルダで1枚目をクリック → 最後をShift+クリック)
- Inspectorで次のように設定して、Apply
- Texture Type:Sprite (2D and UI)
- Sprite Mode:Single
Universal 2Dのプロジェクトでは、取り込んだ画像のSprite Modeが最初からMultipleになっていることがあります。Multipleのままだと「slime_walk_61_0」のように名前が変わり、UIのImageに入れるときに分かりにくくなるので、Singleにしておきましょう。
ウインドの枠(UI/ui_window)だけは、もう1つ設定があります。四角い枠を、角をつぶさずに好きな大きさに伸ばせるようにします。
ui_windowを選んで、InspectorのSprite Editorを押す- 右下のBorderの L・T・R・B を、すべて24にして、上のApply
- 緑の線で、絵が9つに区切られる(角の4つは伸ばさず、辺と真ん中だけを伸ばす)
日本語のフォント
メッセージやコマンドに日本語を出したいのですが、TextMeshProに最初から入っているフォントには日本語がありません。zipに入っているNoto Sans JPからフォントアセットを作ります。
TurnBasedRpg/FontsのNotoSansJP.ttfを右クリック>Create>TextMeshPro>Font Asset>SDF- 「NotoSansJP SDF」が出来る(Atlas Population ModeはDynamicのまま。使った文字だけをその場で用意してくれます)
- 出来たNotoSansJP SDFを選び、InspectorのGeneration SettingsにあるMulti Atlas Textures にチェックを入れる
- RPGはメッセージの文字の種類が多いので、文字を書きこむ画像(アトラス)が1枚でいっぱいになったときに2枚目を作ってくれるようにしておきます
- Edit>Project Settings>TextMesh Pro>Settings のDefault Font Assetに、NotoSansJP SDFを入れる
- 新しく作るテキストが、最初から日本語で表示されるようになる
- 初めてTextMeshProを使うと「TMP Importer」のウインドが出るので、Import TMP Essentialsを押す


フォントアセットの作り方は、9-3 TextMeshProで美しいテキストを表示しようで詳しく紹介しています。
Canvasを用意しよう
画面の部品は、キャラクターも含めてUIで作ります(Canvasの基本は9-1 UnityのUI(Canvas)システムを知ろう)。
- Hierarchyで右クリック>UI (Canvas)>Canvas(EventSystemも一緒に出来ます)
- Canvasを選んで、Inspectorで次のように設定
- Render Mode:Screen Space – Camera
- Render Camera:Main Cameraをドラッグ
- Canvas Scalerを次のように設定
- UI Scale Mode:Scale With Screen Size
- Reference Resolution:X 1920、Y 1080
- Match:0.5


- Screen Space – Camera
- UIを、カメラの前に置いた板のように映す設定
- 最初のScreen Space – Overlayは「カメラと関係なく画面の一番手前に描く」ので、パーティクル(火花やまほうのキラキラ)をUIの手前に出せない
- このシリーズでは#8の攻撃や#13のまほうでエフェクトを出すので、最初からカメラに映す設定にしておきます
- Match:0.5
- 画面の縦横比が1920×1080と違うとき、幅と高さのどちらに合わせるか。0.5は「両方の間」で、PCのいろいろなウインドの大きさでもはみ出しにくい
画面を場所ごとに分けよう
いよいよレイアウトです。最終的なHierarchyは次の形になります。
- Canvas
- Background(書庫の背景)
- Stage(味方と敵が並ぶ場所)
- PartyArea
- Fairy
- Slime
- Jiangshi
- EnemyArea
- SpilledInk
- PartyArea
- MessageWindow
- MessageText
- CommandWindow
- StatusWindow


Hierarchyで下にあるものほど、画面では手前に描かれます。背景を一番上、ウインドを一番下にしておくと、キャラクターが動いてもメッセージやコマンドが隠れません。
背景とStage
Canvasの子に、次のものを作ります。アンカーは、Rect Transformの左上の四角いボタンで選び、そのあと位置と大きさの数字を入れます。
- Background(UI (Canvas)>Image)
- アンカー:stretch-stretch、Left・Top・Right・Bottom:0(画面いっぱいに広がる)
- Source Image:bg_library_b1
- Stage(Create Empty)
- アンカー:stretch-stretch、Left・Top・Right・Bottom:0
- 中身が無い入れ物ですが、#8で攻撃が当たったときにStageごと揺らして、画面が揺れたように見せるために分けておきます
- Stageの子にPartyArea(Create Empty)
- アンカー:middle-left、Pos X:440、Pos Y:60、Width:600、Height:560
- Stageの子にEnemyArea(Create Empty)
- アンカー:middle-right、Pos X:-560、Pos Y:60、Width:900、Height:560
アンカーを「左」「右」にしておくと、画面の横幅が変わっても、味方は左、敵は右にくっついたままになります。
3つのウインド
ウインドは、ui_windowをSlicedで伸ばして作ります。3つとも、Canvasの子にUI (Canvas)>Imageで作り、Source Imageにui_window、Image TypeをSlicedにします。
| 名前 | アンカー | Pos X | Pos Y | Width | Height |
|---|---|---|---|---|---|
| MessageWindow | top-stretch(Left・Right:60) | - | -100 | - | 120 |
| CommandWindow | bottom-left | 250 | 150 | 420 | 260 |
| StatusWindow | bottom-stretch(Left:480、Right:60) | - | 150 | - | 260 |
- MessageWindowの子にText – TextMeshProで「MessageText」を作る
- アンカー:stretch-stretch、Left・Right:40、Top・Bottom:0
- テキスト:「こぼれたインクが あらわれた!」、Font Size:44、Alignment:左寄せ・上下中央、Color:白


Image TypeがSimpleのままだと、四角い枠がまるごと引き伸ばされて、白いふちが太くなったり、角がつぶれたりします。枠の絵を伸ばすときは、Sprite EditorのBorderとImage Type:Slicedをセットで使いましょう。
仲間と敵を並べよう
PartyAreaの子に、3人をUI (Canvas)>Imageで作ります。横から見たRPGらしく、奥の人ほど左上にずらして斜めに並べます。
| 名前 | Pos X | Pos Y | Source Image |
|---|---|---|---|
| Fairy | -190 | 140 | fairy_walk_61 |
| Slime | 0 | 0 | slime_walk_61 |
| Jiangshi | 190 | -140 | jiangshi_walk_61 |
- 3人とも アンカー:middle-center、Width・Height:340、Preserve Aspectにチェック(絵の縦横比を保つ)
- Hierarchyでは、奥のFairyを上、手前のJiangshiを下にする(手前の人が上に重なるように)
EnemyAreaの子に、敵を1体置きます。
- SpilledInk(UI (Canvas)>Image)
- アンカー:middle-center、Pos X・Pos Y:0、Width・Height:380
- Source Image:enemy_spilled_ink、Preserve Aspectにチェック


その場で弾ませよう
このままだと止まった絵のままなので、待機のコマを切り替えて、その場で弾むようにします。
- TurnBasedRpg/Scriptsに「IdleBounce」スクリプトを作る
using UnityEngine;
using UnityEngine.UI;
// 待機のコマを 1→2→3→2 の順に切り替えて、その場で弾ませる
public class IdleBounce : MonoBehaviour
{
[SerializeField] private Image image;
[SerializeField] private Sprite[] frames; // walk_61・walk_62・walk_63
[SerializeField] private float frameSeconds = 0.15f; // 1コマを出しておく時間
// 3枚を 1→2→3→2 の順に使う(2枚目を折り返しに使うと、なめらかにつながる)
private static readonly int[] frameOrder = { 0, 1, 2, 1 };
private float timer;
private int orderIndex;
private void Start()
{
// 3人が同じタイミングで弾まないように、始めるコマをずらす
orderIndex = Random.Range(0, frameOrder.Length);
image.sprite = frames[frameOrder[orderIndex]];
}
private void Update()
{
timer += Time.deltaTime;
if (timer < frameSeconds)
{
return;
}
timer -= frameSeconds;
orderIndex = (orderIndex + 1) % frameOrder.Length;
image.sprite = frames[frameOrder[orderIndex]];
}
}
- frameOrder
- 3枚の絵を「何番目の順に使うか」の表。1→2→3→2→1→2→3・・・とくり返す
- 1→2→3→1だと、3から1にいきなり戻るので動きがカクッとなる。2枚目を折り返しに使うとなめらかになります
- Start
- 3人が同じコマから始めると、そろって弾んで、ちょっと不自然に見える。始めるコマをランダムにずらしておく
- timer
- 経過時間をためて、frameSeconds(0.15秒)をこえたら次のコマにする
timer = 0ではなくtimer -= frameSecondsにしているのは、こえた分を次に持ち越して、コマの長さをそろえるため
- %(あまり)
(orderIndex + 1) % 4は、0→1→2→3→0とくり返す。表の最後まで行ったら最初に戻る
スクリプトを付けて、Inspectorで設定します。3人とも同じ手順です。
- IdleBounceを、HierarchyのSlimeにドラッグ&ドロップ
- Image:Slime(自分自身)をドラッグ
- Frames:ProjectウインドでSlimeフォルダのslime_walk_61〜63を選んで、InspectorのFramesの文字の上にドラッグ&ドロップ
- 61・62・63の順に並んでいるかを確認
- FairyとJiangshiにも、それぞれの絵で同じように設定する


動かして確認!
再生して、3人がばらばらのタイミングで弾めば成功です!


続けて、画面の比率を変えてもくずれないか確かめておきましょう。
- Gameビューの解像度のドロップダウンで、16:10 Aspectに切り替えてみる


#1の動作確認
- 3人が、その場でなめらかに弾んでいる(そろって弾まない)
- 味方が左、敵が右、メッセージが上、コマンドとステータスのウインドが下にある
- ウインドの白いふちが、どれも同じ太さで、角が丸いまま
- 16:10にしても、部品同士が重ならない
- 「こぼれたインクが あらわれた!」の日本語が表示されている



ウインドが空っぽなので、まだちょっとさみしいですね・・・



#3でHPとMPのゲージ、#4でコマンドを入れていくよ!もうRPGの画面っぽくなってきたでしょ?
あとがき
今回はプロジェクトを作って、サイドビューのバトル画面のレイアウトを決めました。まだ戦えませんが、書庫の中で3人がぷるぷるしているだけでも、RPGが始まりそうな気がしてきますね。次回は、キャラクターと敵の名前やHP・攻撃力などを入れておく「データ」をScriptableObjectで作りたいと思います!
コメント
コメント一覧 (1件)
[…] 前回:#1 プロジェクトの準備とバトル画面のレイアウト […]