クリックすると、テキストと立ち絵とボイスが出ます。
Unityで作るノベルゲーム第5回は、テキストや画像、音などの素材をCSVで呼び出す方法を紹介します。
- 第0回:「画面サイズ変更、ボタンとテキスト作成、UIの操作 」
- 第1回:「ExcelでCSVを作成して読み込む」
- 第2回:「画面クリックした回数だけCSVのテキストを表示する」
- 第3回:「csvのテキストを画面上に表示する」
- 第4回:「同時にボタンと画面処理しない」
- 第5回: 【本記事】
- 第6回:「Auto機能の実装」
- 第7回:「クイックセーブ・ロードの実装」
- 第8回:「改造されないセーブ・ロード実装」
前々回(第3回)は、画面をクリックすると1つ1つテキストが表示されるところまで制作しました。
そして、前回(第4回)は、UIボタンを押すと同時に画面クリックも処理されてしまうので、「EventSystem.current.IsPointerOverGameObject()」を使って、UIボタンの上にマウスカーソルがあるときは画面クリックの処理をしないようにしました。
ノベルゲームと小説の違いは、ノベルゲームは文章(テキスト)だけではなく、登場人物の立ち絵や挿絵(CG)、ボイスなどがあり、これこそが魅力でもあります。
また、これらの素材は画面クリックやAuto機能に応じて出力されます。
この時に、立ち絵の表情とテキストがあっていない。ボイスとテキストが一致していないなどのトラブルが発生しやすいです。
今回は、「立ち絵」や「挿絵」、「ボイス」を本シリーズで行っているようにエクセルやGoogleスプレッドシートなどの表計算ソフトでCSVを作成し、これら画像と音の素材をコントロールする方法を紹介します。
エクセルやGoogleスプレッドシートで素材を管理すればバグやミスも軽減できるだけではなく、データ管理に力を注ぐ必要がないため、システム開発やイラストや作曲に集中することができます。
- CSVで画像や音を画面上に表示したい
- ノベルゲームを作りたい
Resources.Load<Sprite>();
Resources.Load<Sprite>()は、指定されたパスのスプライト(画像)を読み込むためのコードです。
読み込みたいスプライトimg.pngをResourcesのImagesに保管したとします。この時のスプライトのパスは「Resources/Images/img.png」というパスにある場合、csvにはResourcesと.pngを除外した「Images/img」すれば、読み込みができます。
「csvData[i][2]」は表計算ソフトでは、A列を0から数えるため、2はC列を示します。
public Image img;
img.sprite = Resources.Load<Sprite>(csvData[i][2]);
(AudioClip)Resources.Load();
(AudioClip)Resources.Load()は指定されたパスのオーディオクリップを読み込むためのコードです。
読み込みたいボイスvoice.mp3をResourcesのImagesに保管したとします。この時のスプライトのパスは「Resources/Voice/voice.mp3」というパスにある場合、csvにはResourcesと.mp3を除外した「Images/voice」すれば、読み込みができます。
private AudioSource audio;
private AudioClip Sound;
void Start()
{
//音声を取得
audio = GetComponent<AudioSource>();
}
void Update()
{
//音声データ
Sound = (AudioClip)Resources.Load(csvData[i][4]);
audio.PlayOneShot(Sound);
}
参考ページ:「Resources-Load – Unity スクリプトリファレンス」
CSVで立ち絵、ボイスを読み込む
CSVで立ち絵、ボイスを読み込むには「Resources.Load()」でパスを読み込めばよいことが分かったかと思います。
ここからは、画面上に立ち絵とセリフを追加していきます。
初めに下準備として、立ち絵とボイスを用意します。
これらの素材を読み込むにはUnityに追加しなければいけません。
Resoucesフォルダーにフォルダーごと追加すると、このように、保管されます。
次にCSVを編集します。
前回までは、名前とセリフしかなかったかと思いますが、今回は、立ち絵とボイスを追加します。
本記事では立ち絵1が左、立ち絵2が右とします。
今回は、太郎と花子の画像それぞれ2枚とボイスがそれぞれ1回ずつあります。
ソースコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //UIを使えるように
using System.IO; //Fileを読み込む
using UnityEngine.EventSystems; //ボタンがクリックで反応する
public class csvcontroler : MonoBehaviour
{
public TextAsset csvFile; //CSVファイル
public static List<string[]> csvData = new List<string[]>(); //csvファイルの中身を入れるリスト
public static int i = 0; //現在地
public Text Nametext; //名前を表示
public Text Logtext; //地の文・セリフ表示
public Image LeftImg; //左の立ち絵
public Image RightImg; //右の立ち絵
private AudioSource audio; //ボイス取得
private AudioClip Sound; //ボイス出力
void Start()
{
//csvファイル
csvFile = Resources.Load("Data") as TextAsset; //Resourcesにあるcsvファイルを格納
StringReader reader = new StringReader(csvFile.text); //TextAssetをStringReaderに変換
while (reader.Peek() != -1)
{
string line = reader.ReadLine(); //1行ずつ読み込み
csvData.Add(line.Split(',')); //csvDataリストに追加
}
audio = GetComponent<AudioSource>(); //音声を取得
}
void Update()
{
//ボタンを押したときは画面クリック無効
if (EventSystem.current.IsPointerOverGameObject()) return;
if (Input.GetMouseButtonDown(0)) //マウス左押下
{
NameText.text = csvData[i][0]; //名前を表示
LogText.text = csvData[i][1]; //セリフ・地の文を表示
LeftImg.sprite = Resources.Load<Sprite>(csvData[i][2]); //太郎の立ち絵に相当
RightImg.sprite = Resources.Load<Sprite>(csvData[i][3]); //花子の立ち絵に相当
//音声データ
Sound = (AudioClip)Resources.Load(csvData[i][4]);
audio.PlayOneShot(Sound);
if (i <= csvData.Count) i++; //csvDataを全て読み込むまで1ずつ追加する。
}
}
}
思い通りのゲームが作れない
Unityでゲーム開発しているけど完成しない。
技術的な壁や知識不足が原因で、思い描いたゲームを実現するのは難しいです。
しかし、Udemyは動画で実践的なゲーム開発を解説していて、
購入した講座は再生・停止・スキップなどが可能なオンデマンド形式なので、
専門的な内容を自分のペースで学習できます。
Unityの機能を網羅したいや作りたいゲームがある人はUdemy学習を取り入れましょう。
数多くある講座の中から特におすすめな講座を3つ紹介します。
Unityのはじめの一歩としておすすめ。開発例に物理挙動やアニメーションを使用しているので、今後の開発が円滑になる。
トランプを題材にした講座。カードゲームやボードゲーム開発に応用可能
UnityエンジンのインストールやC#の文法に加えて、App StoreとGoogle Playにゲームをリリース方法を解説。
解説
初めに名前空間を定義します。
UIを使うための「using UnityEngine.UI;」、CSVを読み込むために「using System.IO;」、UnityのUIイベントシステムを操作する「using UnityEngine.EventSystems;」等々の名前空間が必要です。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //UIを使えるように
using System.IO; //Fileを読み込む
using UnityEngine.EventSystems; //ボタンがクリックで反応する
つづいて、変数を定義します。
csvFileはCSVファイルを格納するための変数です。
csvDataはCSVファイルの内容を格納するためのリストです。
iはint型の変数でCSVファイル内の行を追跡します。
NametextとLogtextはUnityのUIテキストで、それぞれ話者の名前とセリフ・地の文を表示します。LeftImgとRightImgはUnityのUIイメージで、登場人物の立ち絵を表示します。
audioはAudioSourceコンポーネントへの参照します。
Soundは再生する音声ファイルを格納するための変数です。
public class csvcontroler : MonoBehaviour
{
public TextAsset csvFile; //CSVファイル
public static List<string[]> csvData = new List<string[]>(); //csvファイルの中身を入れるリスト
public static int i = 0; //現在地
public Text Nametext; //名前を表示
public Text Logtext; //地の文・セリフ表示
public Image LeftImg; //左の立ち絵
public Image RightImg; //右の立ち絵
private AudioSource audio; //ボイス取得
private AudioClip Sound; //ボイス出力
}
Start関数では、CSVファイルを読み込んでcsvDataリストにデータを追加します。Resources.Loadメソッドを使用して、Resoucesに保管してあるCSVファイル「Data」を読み込みます。
読み込んだCSVファイルはTextAsset型としてcsvFile変数に格納されます。StringReaderを使用してcsvFileを行単位で読み込み、各行をカンマで分割してcsvDataリストに追加します。
また、GetComponent()を使用してオブジェクトにアタッチされたAudioSourceコンポーネントへの参照を取得します。
void Start()
{
//csvファイル
csvFile = Resources.Load("Data") as TextAsset; //Resourcesにあるcsvファイルを格納
StringReader reader = new StringReader(csvFile.text); //TextAssetをStringReaderに変換
while (reader.Peek() != -1)
{
string line = reader.ReadLine(); //1行ずつ読み込み
csvData.Add(line.Split(',')); //csvDataリストに追加
}
//音声を取得
audio = GetComponent<AudioSource>();
}
最後にUpdate関数では、マウスの左ボタンが押されたときに実行されます。
NameText.text = csvData[i][0]; は、UIテキスト「NameText」にCSVファイルのi行目の0番目(A列)の要素を表示します。
LogText.text = csvData[i][1]; は、UIテキスト「LogText」にCSVファイルのi行目の1番目(B列)の要素を表示します。
LeftImg.sprite = Resources.Load(csvData[i][2]); は、UI画像の「LeftImg」にCSVファイルのi行目の2番目(C列)の要素に対応する画像を表示します。
RightImg.sprite = Resources.Load(csvData[i][3]); は、UI画像の「RightImg」にCSVファイルのi行目の3番目(D列)の要素に対応する画像を表示します。
Sound = (AudioClip)Resources.Load(csvData[i][4]); は、CSVファイルのi行目の4番目(E列)の要素に対応する音声ファイルを読み込んでSound変数に格納します。
audio.PlayOneShot(Sound); は、Sound変数に格納された音声を再生します。
if (i <= csvData.Count) i++; は、iがcsvDataの要素数と同じになるまで続けます。
※格納では、0から始まるので、A列は1番ではなく0番目となります。
void Update()
{
//ボタンを押したときは画面クリック無効
if (EventSystem.current.IsPointerOverGameObject()) return;
if (Input.GetMouseButtonDown(0)) //マウス左押下
{
NameText.text = csvData[i][0]; //名前を表示
LogText.text = csvData[i][1]; //セリフ・地の文を表示
LeftImg.sprite = Resources.Load<Sprite>(csvData[i][2]); //太郎の立ち絵に相当
RightImg.sprite = Resources.Load<Sprite>(csvData[i][3]); //花子の立ち絵に相当
//音声データ
Sound = (AudioClip)Resources.Load(csvData[i][4]);
audio.PlayOneShot(Sound);
if (i <= csvData.Count) i++; //csvDataを全て読み込むまで1ずつ追加する。
}
}
実演
では、実際に動作を確認します。
今回のスクリプト「csvcontroler.cs」をHierarchyウィンドウにアタッチをして、InspectorウィンドウにUIを対応させて下さい。
UIのアタッチまでが完了しましたら、再生ボタンを押して実行してください。
以下の動画の通りに動作すれば、成功です。
※今回は音声の出力を確認するため動画で実演しています。動画を再生する際は音に気を付けてからご覧ください。
まとめ
今回は、テキスト以外も画像と音声をCSVを使って画面上に表示しました。
スプライト(画像)を認識するには、「Resources.Load<Sprite>();」を使います。
オーディオクリップ(音)を認識するには、「(AudioClip)Resources.Load();」を使います。
これらを使うことで、「Resouces/Images/…」というようなパスを使って素材の所在を特定し、画面に表示させることができます。