【unity C#】RPGストーリー進行フラグと選択肢の作り方。処理の方法を紹介

フラグ管理って凄く悩みますよね。僕はテキストベースのRPG開発をしていてとても悩みました。今回は僕が実装してみたフラグ管理の方法を書いていきます。もっと効率の良い書き方があるのかもしれませんので、もし気になった方は気軽にコメントしてくださいね。

やりたいこと
こんな感じのCSVで記述をし、フラグ管理をしたい。
フラグ(int) | 進行するストーリー | ストーリーの説明 |
フラグ(int) | 選択肢A | 選択肢Aの説明 |
フラグ(int) | 選択肢B | 選択肢Bの説明 |
フラグ(int) | 選択肢Aを選んだ場合のストーリー | 選択肢Aを選んだ場合のストーリーの説明 |
フラグ(int) | 選択肢Bを選んだ場合のストーリー | 選択肢Bを選んだ場合のストーリーの説明 |
もっと効率の良い方法があるかもしれませんが、精一杯考えた結果、このようなフラグ管理で実装しようと考えました。少しでも参考になれば幸いです。
CSVファイルをスクリプトに読み込む方法
フラグの設定
フラグは以下のように設定しました。複雑になってしまっているので、次の項目で例を交えてしっかりと説明してきます。
フラグ の番号 | フラグの説明 |
-1 | 未開放のストーリー |
0 | 解放中のストーリー |
1~9 | 解放中の選択肢 |
11~19 | 未開放の選択肢 |
21~29 | 選択肢(1~9)を選んだ結果。1桁目が同じ選択肢以外を削除し、最初の1つだけを1桁にして開放 |
90 | 解放済みストーリー。ストーリーの歴史等で確認できる |
91 | 選ばれなかった選択肢等のストーリー。91は全て削除される。 |
97 | 選択肢の開始を指定するフラグ。このエリアから探索する |
98 | 選択肢の終了を指定するフラグ。このエリアまで探索する |
99 | ストーリーの最初と最後を指定するフラグ。このフラグ以降は読み込まない |
フラグ管理の例

例としてドラクエの花嫁を選ぶシーンを今回のフラグ管理で実装します。
以下が構造体とCSVファイルです。CSVファイルから構造体配列に格納した状態で使用します。
構造体
//ストーリーを格納する構造体
public struct STORY
{
public int flag;
public string title;
public string info;
}
//ストーリーの構造体を格納するリスト
public static List<STORY> story = new List<STORY>();
CSVファイル
99,始まり終わり,この項目は表示されません。
0,結婚相手を選ぶ,ビアンカ・フローラ・デボラの誰にしよう
97,嫁を選ぶ選択肢の始まり,この項目は表示されません。
11,ビアンカ,一緒にお化け屋敷に乗り込んだ思い出のあるビアンカを選んだ
12,フローラ,試練も突破したことだし、お嬢様のフローラを選んだ
13,デボラ,ビアンカとフローラなんて選べない。それならとデボラを選んだ
21,ビアンカと話す1,まあ、私を選んでくれたのね
21,ビアンカと話す2,嬉しいわ! あなたと一緒にいれるなんて
21,ビアンカと話す3,お祝いしなくちゃね
22,フローラと話す1,私でいいんですか
22,フローラと話す2,ありがとうございます
22,フローラと話す3,頑張りますね
23,デボラと話す1,私を選んだのね
23,デボラ2,後悔しないでよ
23,デボラ3,それじゃあ結婚式の準備をしましょうか
98,嫁を選ぶ選択肢の終わり,この項目は表示されません。
-1,花嫁を選んだ,ついに結婚式だ
-1,結婚式,ふたりは結婚した
99,始まり終わり,この項目は表示されません。
処理の方法
ストーリーは0~9を開放して選択できる状態にします。ですので、ストーリーが選択された時の現在のフラグは必ず0~9になります。
現在のフラグが0の時
では、さっそく『結婚相手を選ぶ』が選択された時の処理を考えていきます。
if(現在のフラグ==0){
switch(次のフラグ){
case -1:
//次のフラグを0にして開放
//現在のフラグを90にして解放済みに
break;
case 97:
//選択肢の開始
//次のフラグが11~19の間。次のフラグを1~9にして解放
//現在のフラグを90にして解放済みに
break;
case 99:
//現在のフラグを90にして解放済みに
break;
}
}
現在のフラグが1~9の時
ここの処理が一番複雑でした。選択肢の基本のフラグ構成は97,1~9,21~29,98のようになっています。
つまり、97と98に囲まれているわけですね。
さらに、21~29の間に追加の選択肢97があった場合の処理も考える必要があります。
if(現在のフラグ1~9の時){
if(次のフラグが97なら){
//選択肢の開始
//次のフラグが11~19の間。次のフラグを1~9にして解放
//現在のフラグを90にして解放済みに
}else if(次のフラグが98なら){
if(次のフラグの次が99なら){//現在のフラグを解放済みに}
else if(次のフラグの次が-1なら){//解放}
else if(次のフラグの次が97なら){//(省略)}
}
else{
while(前のフラグが97になるまで前に戻る){
//前のフラグ(1~9)を91にする
}
//前のフラグ=97なので、前のフラグを91にする
while(次のフラグが98になるまで次に進む){
if(現在のフラグと次のフラグの1桁が一致するなら){
//最初の1つだけを1桁で解放
while(現在のフラグと次のフラグの1桁が一致する間次に進む){}
}
else if(次のフラグが97(追加の選択肢)なら){
//97の数だけ98をスキップ
}else{
//選ばれなかった選択肢とその先のストーリーのフラグを91に
}
}
}
//最後に91をストーリーの配列から削除
//現在のフラグを解放済みに
}//終了
まとめ
少し強引な方法だったかもしれません。完全独学で制作してますので、同じように独学で頑張っている方の参考になればと思います。また、さらに良い方法を知っている方はお気軽にコメントしてください。少しでもゲーム制作を楽しんでいる方々の助けになれるようなブログ運営を目指していきます。

-
前の記事
【unity】文字制限なし。戦闘ログをスクロール可能にして表示する方法 2021.07.15
-
次の記事
【unity】アニメーションがSetTriggerで遷移しない原因と解決方法 2021.07.17