この記事は「恋愛・ホラー風ノベルゲーム」の作り方講座の12章です。
前回までで一通りの会話や選択肢を表示し、背景変更等もできるようになりました。
前の記事:
今回は会話の内容を外部データベースから読み込んでノベルゲーム内で使えるようにしていきます。CSVファイルなどから読み込んでもいいのですが、グーグルスプレッドシートを活用してみます。
ゲームではデータをサーバーに置くことがあります。「外部にあるデータを取り込んでゲームに使用する」という処理を実装していきます。
ゲームデータ用のスプレッドシートの作成
まずはゲームに取り込むための会話データを作成していきます。
グーグルスプレッドシートを開く
今回はGoogleのスプレッドシートを使用します。まずはGoogleのアカウントを作成しておきましょう。
ログインした状態でGoogle検索ページの左上の点々のマークをクリックします。
その中の緑の紙のようなマークをクリックします。
すると下記のようなページになるので、一番左「空白」をクリックします。
すると下記のように白紙のスプレッドシートが開きます。
スプレッドシートは表形式で値を入力して使うことができます。この表をデータベースとみなしてゲーム内で使用していきます。
このマスに入れたデータをUnityに取り込んで使用していきます。
ゲーム取り込み仮データの作成
では、一旦仮のデータを作成してUnityでデータを取得するテストをしてみます。
下記のように入力しましょう。
タイトルはわかりやすいように「GameData001」としました。
入力したいセル(マスのこと)をダブルクリックすれば値を入力できます。
スプレッドシート共有設定の変更
作成したらこのデータの共有設定を変更する必要があります。
スプレッドシート右上に「共有」ボタンがあるのでクリックします。
すると、以下のように共有リンクのアクセス権限を設定できるようになります。
「一般的なアクセス」の欄で”制限付き”から”リンクを知っている全員”に変更します。
これでこのファイルのリンクを知っていれば誰でも開けるファイルとなり、Unityからもアクセスできるようになります。
共有リンクにはなりますが、リンクのURLを知らない人はこのデータを見ることができません。ゲームプレイヤーにリンクを共有しないようにしましょう。
Unityへのスプレッドシート取り込みテスト
ではここから本題のデータの取り込みをおこなっていきます。
通信をしてスプレッドシートを取り込みますので、通信のできる環境で試してください。
取り込み処理のためのC#スクリプトを作成
まず処理を作成します。
「Assets/AppMain/99_Common/Scripts」フォルダ内に「SpreadSheetReader.cs」というC#ファイルを新しく作成します。
下記のように入力します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using Cysharp.Threading.Tasks; public class SpreadSheetReader : MonoBehaviour { void Start() { string _sheetId = "[シートのID]"; string _sheetName = "TestSheet"; LoadSpreadSheet( _sheetId, _sheetName ).Forget(); } public async UniTask LoadSpreadSheet( string id, string name ) { Debug.Log( "読み込み開始" ); UnityWebRequest request = UnityWebRequest.Get( "https://docs.google.com/spreadsheets/d/" + id + "/gviz/tq?tqx=out:csv&sheet=" + name ); await request.SendWebRequest(); if( request.result == UnityWebRequest.Result.ProtocolError || request.result == UnityWebRequest.Result.ConnectionError ) { Debug.Log( request.error ); } else { Debug.Log( "<< 全文 >>\n" + request.downloadHandler.text ); } } } |
短いですが、通信を行なったり複雑な処理も出ていますのでゆっくりみていきましょう。
最初の「using」ですが、「UnityEngine.Networking;」は通信を行う時に使用しています。
「Cysharp.Threading.Tasks;」は待機処理を使うために呼び出します。
次に「Start()」関数ですが、テスト用関数を実行しているものなので後に解説します。
ではここでメインの「LoadSpreadSheet()」関数について見ていきます。
「public async」で返り値は「UniTask」で今まで使用してきたように処理を待機できる関数にします。
引数の一つ目は「string id」で「ID」を指しますが、ここでいうIDは「スプレッドシートのID」となります。
そしてもう一つの引数「string name」はスプレッドシートの「シート名」です。
まずはこの二つが何を指すのかを解説していきます。
スプレッドシートのIDとシート名
まずはスプレッドシートを開いている状態でブラウザでURLを見てください。
1 |
https://docs.google.com/spreadsheets/d/「ここがシートのID」/edit#gid=0 |
URLのうちの「ここがシートID」となっているところに数字アルファベットが入っているかと思います。
この部分が「シートのID」となるので、まずはここをコピペしてどこかにメモしておきます。
この部分は独自の値になるため、以降の解説では「[シートのID]」と記載しますがこれはそれぞれのIDを入力するようにしておください。
そして最初に「GameData001」とつけたのはこのファイルの名前で、「シート名」は下に書いてある「シート1」となっている部分です。
この名前は右クリックから自由に変更でき、またこのファイル内で何個ものシートを作成できます。
この名前でも大丈夫ですが「1」の部分が全角か半角かで別の名前となって紛らわしいので変更しておきましょう。数字は半角を使用する、みたいにルールを決めておくといいです。
現段階では「TestSheet」としておきます。
関数の解説
では関数の解説に戻ります。
改めて「public async UniTask LoadSpreadSheet( string id, string name )」の引数「id」がシートID、「name」がシート名になります。
最初にログを出して読み込みを開始します。次の2行が一番重要です。
1 2 |
UnityWebRequest request = UnityWebRequest.Get( "https://docs.google.com/spreadsheets/d/" + id + "/gviz/tq?tqx=out:csv&sheet=" + name ); await request.SendWebRequest(); |
まずは「UnityWebRequest」という型。
これがUnityで通信を行う時に使用するものです。「request」という変数に実行している「UnityWebRequest」を格納します。
実行している内容を見ていきます。まず引数を抜くと「UnityWebRequest.Get( 〇〇 );」という形です。
これは通信を行いそのレスポンスを取得する関数です。そして引数は「URL」になります。
今回の処理ではURLは「+」を使っていくつかの文字列がパラメータとして結合されてできています。一つずつ見ていきます。
1つ目に文字列「https://docs.google.com/spreadsheets/d/」、3つ目に文字列「/gviz/tq?tqx=out:csv&sheet=」があります。
2つ目は引数の「id」、4つ目が「name」です。
この1、3の文字列はこのままコピペしてしまって構いません。
これはスプレッドシートの値を取得するためのURLで、「id」と「name」を使用してページを決定しています。
次の「await request.SendWebRequest();」で先ほどのリクエスト(値を取得する)を実行し値が帰るのを「await」で待ちます。
完了したらその結果を表示します。
1 |
if( request.result == UnityWebRequest.Result.ProtocolError || request.result == UnityWebRequest.Result.ConnectionError ) |
まず「request.result」という値で「UnityWebRequest.Result」という型で結果がどうなったかを取得できます。
この値が「ProtocolError」「ConnectionError」の場合、文字通りエラーだった場合は
1 |
Debug.Log( request.error ); |
でエラーのログを出します。ここはうまくいかなかった時の処理です。
それ以外の場合は。
1 |
Debug.Log( "<< 全文 >>\n" + request.downloadHandler.text ); |
結果をログに出します。
「request.downloadHandler」はダウンロードしたものをハンドリングするもので、それをそのまま「text」とすれば文字列で結果を取得できます。
この関数を「Start()」内で実行しています。
1 2 3 4 5 6 |
void Start() { string _sheetId = "[シートのID]"; string _sheetName = "TestSheet"; LoadSpreadSheet( _sheetId, _sheetName ).Forget(); } |
「_sheetId」はそれぞれ個別に違う「シートID」。「_sheedName」には変更した「TestSheet」を入れておきます。
そして引数のこの二つを入れて「LoadSpreadSheet()」関数を実行します。待機の必要はないので「Forget()」をつけておきます。
これはあくまでテスト処理です。
結果の確認と見方
ではここまでできたら、作成した「SpreadSheetReader.cs」を「02_Game」シーンのHierarchyで「GameScene」に付与しておきます。
実行してみましょう。
1 2 3 4 |
<< 全文 >> "ABC","あいう","123" "DEF","えお","456" "GHI","かきく","789" |
このようなログが出たでしょうか。これが出ていれば成功です。
うまくいかない場合は通信状況やスプレッドシートの共有設定を確認してください。
「<<全文>>」は処理内で追加したものなので除いて、それ以外の部分が結果となります。
このように各要素が「” “」で囲まれた文字列として取得できました。
これでグーグルスプレッドシートからUnityのゲーム内にデータをロードができました。
今回の講座ではこのやり方でスプレッドシートから得た文字列を解析してゲームで必要なデータとして使用できるようにします。
スプレッドシートで会話データの作成
ではここからスプレッドシートに会話に使用するデータを作成していきましょう。
シートを追加
では先ほどのシートとは別にデータを作成します。
スプレッドシートの左下の「+」を押すとシートを追加できますので、追加して「TalkData001」という名前にしておきましょう。数字は半角にしてください。
ノベルゲームの会話に必要な項目の整理とデータシートの設計
まずは何が必要か考え、データをどういう形で入れていくか設計していきます。
今回は会話の内容をデータにするので、まずは「会話内容」。
そしてそれを「話しているキャラクターが誰か」。
その時の「キャラ画像」を「左右と真ん中」。
最後に「背景の画像」。
これらが今回必要な項目になります。
まずはこれらを下記のように「1」の行に左から「場所」「発話キャラ(選択肢は30)」「内容」「左」「真ん中」「右」と入力します。
これらはデータそのものではなく、各列が何のデータを表すかを示しています。シート中には書かなくてもいいのですがシートだけ見たときに各列が何を表していたか書いておく方が便利です。
さて、ここから仕様を決めていきましょう。
場所
背景画像を表すデータで「夜の学校前」など文字で入力して、それを基にして画像を決定します。
発話キャラ
誰が話しているかを表すデータです。
ここまでの章では仮データ欄でキャラを数字で表してきました。
同じように今回は「1」、「2」、「3」のように数字を使用してキャラクターを表し「30」を選択肢の時の番号とします。
内容
会話の内容です。
ここに入力した文字列データをそのまま会話内容とします。
左、真ん中、右
表示するキャラ画像の左、真ん中、右それぞれのデータです。
記入方法は「1Egao」のように、キャラを表す数字「1」と表情、画像を決めるための「Egao」部分を合わせて記入します。
これも仮データと同じ表記方法です。
これらの項目を会話1ページにつき1行のデータとして記入していきます。
ゲームデータの作成
それではゲームに使うデータを作成していきましょう。
あくまでテストデータなので会話内容以外の表情など適当な部分もあります。それなりのデータ量なので好きにアレンジしても構いません。
上記の内容を以下で表にしておきます(以下の表では改行は省いているので全く同じにする場合は上の画像のようにセル内で改行を入れてください)。
場所 |
発話キャラ |
内容 | 左 | 真ん中 | 右 |
学校前 | 2 | うーん。今日の待ち合わせ場所ってここだったよな。 | 2Egao | ||
2 | 俺はどこにでもいる普通の高校生。 現在時刻は23時30分。夜の高校の前に来ている。 なぜこんな夜の学校に高校生が制服で来てるのかと言うと・・・ | 2Egao | |||
1 | お待たせ―!ごめんごめん待った? 全然遅刻してないよね? | 1Egao | 2Egao | ||
2 | 30分遅刻だわ! | 1Egao | 2Egao | ||
1 | あ?そうだっけー? ごめんごめん。まあ許してあげてよ? かわいい幼馴染が夜のデートしてあげるんだからさ? | 1Nakigao | 2Egao | ||
2 | この調子の良い明るい女子学生は幼馴染で同級生の「真先帰宅」。 よく遅刻する。 | 1Nakigao | 2Egao | ||
2 | はいはい。で、なんでこんな時間に学校に呼び出したの? | 1Nakigao | 2Egao | ||
1 | ふふふ~。実はねー! この学校、夜の0時ジャストに出るらしいんだよね~。 | 1Nakigao | 2Egao | ||
2 | 出るって何が? | 1Nakigao | 2Egao |
1 | お・・・ば・・・け! 幽霊が出るって噂があってね。 | 1Nakigao | 2Egao | ||
1 | イタコの娘の帰宅ちゃんとしては調べないわけにはいかないよね~ | 1Nakigao | 2Egao | ||
2 | え?それで俺呼び出されたの? | 1Nakigao | 2Egao | ||
2 | マジか・・・ 告白でもされるのかな?って思ってたけどそんな理由だったのか。 勘弁してくれ・・・ | 1Nakigao | 2Egao | ||
1 | そうだよ?不審者出たりホームレスが住み着いてたりしたら怖いでしょ? | 1Egao | 2Egao | ||
2 | いやー夜の学校にわざわざ来ないかと | 1Egao | 2Egao | ||
1 | うるさいなー!はい!行くよ! | 1Egao | 2Egao | ||
2 | 幼馴染に腕を取られてしぶしぶ夜の学校に侵入することとなった。 | 2Egao | |||
夜の教室 | 2 | 2Egao | |||
2 | よし。夜の学校に潜入完了。さてどこに行こう? | 2Egao |
30 | 教室,音楽室,職員室 | 2Egao |
作成データの読み込み
では先ほどと同じように、作成したデータを読み込んでみましょう。
変更するのは「SpreadSheetReader.cs」の「Start()」内にテスト用に作成していた処理の、シート名です。
読み込みデータで会話を再生
ではUnityエディタを再生してみましょう。
再生してみるとこのままではNullエラーが出るはずです。これはスプレッドシートの背景データがここまでの講座内容で用意したBackGround DataのScriptable Objectに存在していないためです。
↑暫定的ですがこのように初期の背景画面を追加しておきます(ゲーム内容としては夜の学校背景画面の方がよさそうですね。ぜひご自分でも画像を変更してみてください)。
これでスプレッドシートからデータを読み込んで会話を表示することができるようになりました。
(↑の動画は全部添付すると長いのでスキップしています)
今回は選択肢で終わりになっていますが、「TalkStart()」関数の返り値には何を選択したかという情報が入っていますので、これを使用して続きは何を表示するかの変化を付けることもできます。
以上で今回の記事は終了となります。
次回は今回までの会話処理にさらにいくつかの機能を追加していきます。
次回の記事:
コメント