画面をクリックすると、Consoleウィンドウにcsvのデータを1つずつ表示する。
Unityで作るノベルゲーム第2回は、「Unity」で読み込んだcsvのテキストをクリックに応じて読み込みます。
- 第0回:「画面サイズ変更、ボタンとテキスト作成、UIの操作 」
- 第1回:「Excel(表計算ソフト)でCSVを作成して読み込む」
- 第2回: 【本記事】
- 第3回:「CSVのテキストをスクリプトでUITextを操作、画面に表示する」
- 第4回:「ボタンクリックで画面クリック判定しない方法」
- 第5回:「CSVでテキスト、画像、音をパスで認識して呼び起こす方法」
- 第6回:「Auto機能の実装」
- 第7回:「クイックセーブ・ロードの実装」
- 第8回:「改造されないセーブ・ロード実装」
前回までの製作は、CSVをUnityに導入し、そのファイルを読み込みました。
しかし、前回のスクリプトは、読み込んだCSVファイルを一度にコンソール(console)表示するものでした。
この出力が意味することは、画面上にすべてのテキストを表示することになります。
したがって、今回は、「Unity」で読み込んだCSVを、テキストを画面クリックをするごとに1つ1つ表示するシステムを作成して、よりノベルゲームに近づけていきます。
本記事では、第1回のプログラムを変更して、画面をクリックすると、CSVファイルのデータを1つずつ表示する方法を紹介します。
- ノベルゲームを作りたい。
- 「Unity」でCSVのテキストを一つ一つ表示したい。
- 画面クリックで表示文字を制御したい。
マウスクリック
UI(User Interface)は、デザイン、背景などのユーザーが視覚から得る情報があり、「Unity」では、HierarchyウィンドウからボタンやテキストなどのUIを使用できます。
UIボタンをクリックして、シーン切り替えをするように、UIや画面をマウスクリックして実行することが可能です。
マウスボタンが押されているかどうかを検出するためのメソッドは「Input.GetMouseButton」を使用します。
このメソッドは、以下のようにタイミングで使い分けることができます。
メソッド | 備考 |
Input.GetMouseButton | ボタンが押されていたら動作 |
Input.GetMouseButtonDown | ボタンが押されたら動作 |
Input.GetMouseButtonUp | ボタンが離れたら動作 |
太字のメソッド「Input.GetMouseButtonDown」は特に使用します。
また、マウスクリックの取得は以下のような0や1のような引数を使用します。
引数 | 検出対象 |
0 | 左クリック |
1 | 右クリック |
2 | マウスホイール |
それでは、メソッド「Input.GetMouseButton」を使ってマウス入力を取得していきます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseClick : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0))//マウス左押下
{
Debug.Log("左クリックされました");
}
else if (Input.GetMouseButtonDown(1))//マウス右押下
{
Debug.Log("右クリックされました");
}
else if (Input.GetMouseButtonDown(2))//マウスホイール押下
{
Debug.Log("ホイールクリックされました");
}
}
}
スクリプト「MouseClick」をHierarchyウィンドウにアタッチして再生ボタンを押します。
実際の動作は次のようになります。
※参考ページ:「【初心者Unity】マウス入力の取得方法」
マウス入力した回数だけCSVのテキストを表示する
マウス入力(Input.GetMouseButton メソッド)の使用方法を確認しました。
ここからは、画面クリックに応じてCSVのテキストを表示します。
今回のソースコードは、第1回のソースコードを修正と追加していきます。
ソースコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO; //追加
public class csvReader : MonoBehaviour
{
private TextAsset csvFile;
private List<string[]> csvData = new List<string[]>();
int i = 0; // 現在の行を示すインデックス
void Start()
{
csvFile = Resources.Load("Sample") as TextAsset; // "Sample.csv"を読み込む
StringReader reader = new StringReader(csvFile.text); // CSVファイルの内容をテキストとして読み込む
while (reader.Peek() != -1) // テキストの終端に達するまでループ
{
string line = reader.ReadLine(); // 1行読み込む
csvData.Add(line.Split(',')); // 読み込んだ行をカンマで分割し、リストに追加する
}
}
void Update()
{
if (Input.GetMouseButtonDown(0)) // マウスの左ボタンが押された場合
{
// 現在の行のデータをログに表示
Debug.Log("日本語:" + csvData[i][0] + ", English:" + csvData[i][1]);
if (i < csvData.Count) // 現在の行がデータの最後の行でない場合
{
i++; // インデックスを次の行に進める
}
}
}
}
思い通りのゲームが作れない
Unityでゲーム開発しているけど完成しない。
技術的な壁や知識不足が原因で、思い描いたゲームを実現するのは難しいです。
しかし、Udemyは動画で実践的なゲーム開発を解説していて、
購入した講座は再生・停止・スキップなどが可能なオンデマンド形式なので、
専門的な内容を自分のペースで学習できます。
Unityの機能を網羅したいや作りたいゲームがある人はUdemy学習を取り入れましょう。
数多くある講座の中から特におすすめな講座を3つ紹介します。
初夏のセール開催中!(5月23日まで)
対象のコースが1300円から。
Unityのはじめの一歩としておすすめ。開発例に物理挙動やアニメーションを使用しているので、今後の開発が円滑になる。
トランプを題材にした講座。カードゲームやボードゲーム開発に応用可能
UnityエンジンのインストールやC#の文法に加えて、App StoreとGoogle Playにゲームをリリース方法を解説。
解説
初めに名前空間に「using System.IO;」を追加します。
これにより、「File」クラスを使用してファイルを読み込んだり、書きこんだり、データを列挙することが可能になります。
using System.IO; //追加
つづいて、変数を定義します。
csvFileはTextAsset型の変数で、CSVファイルの内容を格納します。
Resources.Loadメソッドを使用して、”Sample”という名前のCSVファイルを読み込んでいます。このCSVファイルはUnityのResourcesフォルダ内に配置されている必要があります。
StringReaderクラスを使用して、csvFile.textからCSVファイルの内容を読み込みます。
csvFile = Resources.Load("Sample") as TextAsset; // "Sample.csv"を読み込む
StringReader reader = new StringReader(csvFile.text); // CSVファイルの内容をテキストとして読み込む
while文でreader.Peek()メソッドを使用して、テキストの終端に達するまでループします。
ループ内では、reader.ReadLine()メソッドを使用してCSVファイルの1行を読み込みます。その後、line.Split(‘,’)を使用して行をカンマで分割し、結果をcsvDataリストに追加します。このリストは、CSVファイルの各行を文字列配列として格納するために使用されます。
while (reader.Peek() != -1) // テキストの終端に達するまでループ
{
string line = reader.ReadLine(); // 1行読み込む
csvData.Add(line.Split(',')); // 読み込んだ行をカンマで分割し、リストに追加する
}
Updateメソッド内では、マウスの左ボタンが押された場合に実行されて、現在の行のデータをログに表示しています。
メソッド「Input.GetMouseButtonDown(0)」で、マウスの左クリックの条件としたif文でCSVのテキストを表示します。
このとき、csvDataリストのi番目の行から、日本語と英語のデータを取得して表示しています。
前回は、For文を使っていましたが、一度に読み込むことを避けるため、メソッド「Input.GetMouseButtonDown(0)」の条件下に、int型変数「i」がString型変数「csvData」よりも小さいときiを1だけ加算するようにします。
つまり、左クリックして、csvのデータよりも少ないときはiを1だけ増やしています。
void Update()
{
if (Input.GetMouseButtonDown(0)) // マウスの左ボタンが押された場合
{
// 現在の行のデータをログに表示
Debug.Log("日本語:" + csvData[i][0] + ", English:" + csvData[i][1]);
if (i < csvData.Count) // 現在の行がデータの最後の行でない場合
{
i++; // インデックスを次の行に進める
}
}
}
- StartメソッドFor文の処理をやめて、Updateメソッドでif文を使っている。
For文・Updateメソッドの注意点
「Unity」を開発していくときに、このプログラムで正常に動くか確認をするときはDebug.Log()を使います。
For文・Updateメソッドどちらも使用頻度は高いですがこれらを安易に使用すると、ループから抜け出せず、使用しているパソコンがフリーズしてしてしまう可能性があります。最悪の場合、開発していたデータが消えてしまう恐れもあります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Sample : MonoBehaviour
{
int num;
void Update()
{
num++;
Debug.Log(num);
}
}
上記のソースコードを実行すると、Consoleウィンドウには、数字が永遠に加算されて表示されます。
データ破損しないように十分に扱いは気を付けてください。
実演
スクリプト「csvReader」は前回と同様なため、ソースコードを保存(「Ctrl」+「S」)すれば、再度Hierarchyウィンドウにアタッチする必要はありません。
再生ボタンを押すと、冒頭で紹介したように、画面のクリックするごとにキャラクターそのセリフが表示されます。
まとめ
CSVを読み込んだ「Unity」のテキストをマウスクリックで1つずつ進めるには、if文でメソッド「Input.GetMouseButtonDown(0)」を使用します。
今回紹介した方法を使えば、ノベルゲームは画面のクリック回数に応じてテキストを表示するシステムに近づきます。
スクリプトで画面に文字を表示する方法
第3回は、画面クリックした回数だけ画面の文字を表示する方法解説しています。
付録.エラーを解決
ここからは「Unity」の開発で想定しうるエラーを提示します。
本製作以外でも、エラー文が表示されないけれど、思うように実行ができないことは多くあります。
変数が進まない
前回はStartメソッドにあったFor文をUpdateメソッドに入れて、ループしないようにif文に修正しました。このとき、以下のようなコードを作成しました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO; //追加
public class csvReader : MonoBehaviour
{
private TextAsset csvFile;
private List<string[]> csvData = new List<string[]>();
void Start()
{
csvFile = Resources.Load("Sample") as TextAsset; // "Sample.csv"を読み込む
StringReader reader = new StringReader(csvFile.text); // CSVファイルの内容をテキストとして読み込む
while (reader.Peek() != -1) // テキストの終端に達するまでループ
{
string line = reader.ReadLine(); // 1行読み込む
csvData.Add(line.Split(',')); // 読み込んだ行をカンマで分割し、リストに追加する
}
}
void Update()
{
///////////////////Updateメソッドに導入//////////////////
int i = 0;
///////////////////////////////////////////////////////
if (Input.GetMouseButtonDown(0)) // マウスの左ボタンが押された場合
{
// 現在の行のデータをログに表示
Debug.Log("日本語:" + csvData[i][0] + ", English:" + csvData[i][1]);
if (i < csvData.Count) // 現在の行がデータの最後の行でない場合
{
i++; // インデックスを次の行に進める
}
}
}
}
エラー文がでなかったものの、実行をすると、次のデータが表示されない。つまり、変数が0のままで進まない。
対処法
ポイントは、Updateメソッド内でint iがあること。
前回のスクリプトからfor文を崩しているので、同じメソッド内に置けばよいと考えやすいです。
しかし、Updateメソッドは更新を繰り返すので、この中で初期化すると、どんな処理を加えてもその変数は変わらず、iは1のまま変化しません。
したがって、前述したように、csvReadrクラスの直下、あるいは、Startメソッド内に移せば、解決します。
Updateメソッドは更新を繰り返すので、基本的に変数はその場で定義しない。