今回はUnityの2Dゲームにて、NPCオブジェクトに触れるとゲームが停止して会話が始まるスクリプトを配布いたします。
↓は会話システムを導入したサンプルゲームです。猫っぽい何かがNPCに触れると会話がはじまります。(スマホ未対応。キーボードのADで左右移動、スペースでジャンプ、ADorスペースorクリックで会話送り。)
なかなか綺麗な設計とは言い難く、少々導入方法が複雑となりますが、配布スクリプトをAIに読み込ませる等でプロンプトに使用してアレンジしていただければと思います。
今回は文字を表示する機能のみのため、表示用の枠が欲しい場合には別途、枠の表示非表示の機能を追加してください。(難しければこれも生成AIにお願いしてみてください)
(githubにてご指摘やアドバイスをいただけると飛び上がるほど喜ぶかと思います...)
Unity2Dでセリフを表示するスクリプト、8つのパーツ
パーツが多くて、うげっとなるかもですが一つずつみていきましょう。
導入中はところどころがエラーになるかもですが、全ての適用が完了するまでは無視で大丈夫です。
- セリフのテキストデータ管理の形を定義する DialogueLineFormat.cs
- セリフのテキストデータを格納する DialogueData.asset (これ手で作った方が色々と良さそう)
- セリフ表示のメインパーツ LinesManager.cs
- セリフ表示処理用のスクリプトを呼び出す NPCController.cs
- セリフを表示するTextUIをヒエラルキービューの+ボタンで好きな位置に配置 文字は空欄
- ゲームのポーズ処理を行う GameManager.cs
- プレイヤーに会話NPCとの接触を感知する機能を追加、停止処理の追加 PlayerController.cs
(ここまで完了するまでの間はエラーが出続けると思います) - 日本語を表示する場合に必要な日本語対応フォント これはお好みで、今回は小杉丸をGogogle Font からダウンロード
Unityでセリフのテキストデータを管理する方法
DialogueLineFormat.cs をAsset下のお好みの場所におきます。
セリフを表示するにも、どこかに会話内容テキストを保存しておく必要があります。
ゲームで必要な会話演出で使用する素材の指定なども、このデータ管理で定義します。
私の今回の会話データはテキストに書き起こすと以下のような形で管理されています。
(⚠️下記はコピー不要です。形のイメージで作成したテキストです。)
{
"dialogues": [
{
"dialogueId": "PST1001",
"lines": [
{
"IconID": "chi_normal",
"Name": "???",
"Line": ["こんにちは。", "わたしは、ねこ。"]
},
{
"IconID": "chi_normal",
"Name": "ちー",
"Line": ["ねこの、ちーだよ。", "ごしゅじんにあげる、", "きれいなおみやげ、おしえて?"]
},
{
"IconID": "boku_normal",
"Name": "???",
"Line": ["やあ。こんにちは。", "ぼくは、", "、", "、", "。"]
},
{
"IconID": "boku_normal",
"Name": "ぼく",
"Line": ["ぼくだよ。", "このあたり、おちてる", "きれいなたま、どう?", "きっとよろこぶよ。"]
},
{
"IconID": "chi_normal",
"Name": "ちー",
"Line": ["ありがと。"]
}
]
}
]
}
- "dialogues"は複数の会話内容全体を格納します。
- "dialogueId": "PST1001"これは、PST1001という会話IDの会話を格納します
- "lines"これはテキストフィールドに表示する会話テキストや名前、アイコンデータなどを管理します(今回使用しているのはNameとLineだけ)
IconIDからLineまでのひと塊りが、テキストフィールドに表示され、ページ送りをすると次を表示という動きになります。
例えば、IconIDやName以外にも、音声データや背景の立ち絵の動き方などを指定できる構造にすることでさまざまなゲームに使用できます。
このテキスト保存形式を定義しているのが、DialogueLineFormat.csです。
スクリプト内の下記の行のおかげで、このDialogueLineFormat.csをAssets内に保存しておくとUnityで定義した通りの会話データを入力できるメニューがUnityに追加されます。
Unity->Create 下に ScriptableObjects->DialogueDataが追加されます。
[CreateAssetMenu(fileName = "DialogueData", menuName = "ScriptableObjects/DialogueData", order = 1)]
Unity上で追加した会話データ作成ようメニューを呼び出してセリフ追加
先ほど、DialogueLineFormat.csを配置したおかげでメニューが追加されているかと思います。
クリックするとプロジェクトフォルダにDialogueDataが作成され、それを選択するとインスペクタービューで会話データの追加が可能です。
下図は、今回追加したデータの一部です。
Icon ID項目は作っただけで使用していないのでてきとうにDummyと入力しました。
Dialogure Id が一度の会話イベントの範囲Icon〜Line(Element)までが1ページのテキストフィールドに表示されるデータです。
説明が上手ではなくて申し訳ないですが、ここで今一度デモのゲームを動かしてみるとイメージが沸きやすいかと思います。
Unity2Dでセリフを表示するスクリプト本体 メインパーツ
会話テキストを表示するためのTextUIをお好みの場所に定義してください。
(今回はTextUIに会話テキストを表示するだけのものです。枠やアイコンが欲しい場合はご自身で機能実装をお願いいたします。)
下記にメインのスクリプトが置いてありので、ダウンロードをお願いします。
- LinesManager.cs をAsset下の好きな場所へ配置
- 会話開始用NPC素材をマップに配置
- ボックスコライダー2Dをアタッチ、isTriggerをON
- セリフを表示したい位置に文字なしのTextUIを設置
次にインスペクタービューからTalkNPCにアタッチしたLinesManager.cs のPublic変数を設定します。
Line Text : 表示先のTextUIをヒエラルキービューからドラッグドロップで設定してください。
Char Display Interval :1文字ずつの表示間隔を指定してください。(今回のスクリプトは1文字ずつ表示します)
Line End Delay:1行表示後、次の行を表示するまでの間隔を指定してください。
Dialogue Id:どの会話IDを表示するか指定してください。( DialogueLineFormat.cs 追加後に増えたメニューで追加した会話データで定義したIDです)
Dialogue Data:DialogueLineFormat.cs の追加で増えたメニューで作成した会話データをプロジェクトビューからドラッグドロップしてください。
Fade Out After Dialogue:会話の後にNPCの姿を消すかどうかのフラグです。特にこだわりがなければOFFで大丈夫です。
NPCControllerスクリプトでPlayer接触時にセリフ表示用スクリプトを呼び出せるようにする
NPCController.cs をAssets下のお好みのフォルダにコピーしてください。
先ほど作成したNPC用オブジェクトにアタッチしてください。
このNPCControllerは、Playerタグオブジェクトとの当たり判定によってアタッチされたLinesManager.csを呼び出すだけのものです。
すでにNPC管理用スクリプトが存在する場合は、OnTriggerEnter2D関数の中身だけをよしなにコピペしていただけたらと思います。
GameManagerにゲーム停止フラグの管理を実装する
ゲームポーズをするかのフラグを定義します。
private bool isGamePaused;
外部から現在のフラグを見るための IsGamePaused() と外部からフラグを設定するための SetGamePaused を作ります。
public bool IsGamePaused()
{
return isGamePaused;
}
public void SetGamePaused(bool paused)
{
isGamePaused = paused;
}
Unityでセリフを表示するためにPlayer用スクリプトに処理を追加
私が使用しているプレイヤー用スクリプトは下記です。
ゲームポーズフラグがONかどうかをみるためにGameManagerを呼び出すための型を作ります。(色々な変数定義してる最初の部分に。)
GameManager gameManager;
Start()関数の中でゲームマネージャーを呼び出します。
gameManager = FindObjectOfType<GameManager>();
ポーズ中に止めたい処理のところで、gameManage.isGamePaused()を使用して停止フラグの確認処理をいれます。
今回は2箇所にいれました。
下記は、歩く処理のところで、ゲーム停止中の場合には左右への力を0にしています。
if(gameManager.IsGamePaused()==true){
axisH = 0;
}
また、ジャンプ関数のところでもフラグを参照するようにしました。
public void Jump(){
if(gameManager.IsGamePaused()==false){
goJump = true;
}
}
一旦、ここまでの設定で動くようになるかと思います。
しかし、ビルドをした際に日本語のセリフが表示されない場合があります。
以下で解決していきます。
Unityでゲームをビルドしたけれど、日本語が表示できない場合の対処
Unity標準のフォントデータを使用していると、ローカルで試しに動かしている時は問題がなくても、
ビルド後に日本語を表示できない可能性があります。
これはUnityのデフォルトフォントが日本語に対応できていないためです。
今回は、日本語対応のフォントをダウンロードして適用しました。
KosugiMaruというフォントを検索し、GoogleFontページからダウンロードします。
ZIPを解凍し、中に入っている .tff ファイルをUnityのAssetsフォルダ下に配置します。
次に、Unityの画面でセリフ表示用TextUIの意スペクタービューでTextコンポーネント->Character->Font に .tff ファイルをドラッグドロップします。
これで対象のTextUIにフォントを指定することができました。
コメント