見出し画像

【通常版】 初めてノベルゲームを作った話 ▷制作過程や実装方法を一挙紹介◁

ブラウザで遊べるノベルゲームを制作・公開しました。
その制作工程や実装方法などを紹介します。

使用したゲームエンジンはUnity、公開した場所はunityroomです。
実装にはUnityで使える無料のノベルゲーム作成ツール「Fungus」を使用しているので、お金をかけずにノベルゲームを作りたいという方の参考になれれば幸いです。

※ちなみに、記事内容は同じですが各項目ごとに特に意味のない一言コメントを付けた記事も同時公開しています。
少し肩の力を抜いて読みたい方は そちらの記事 をお読みください。


ゲームの紹介

まずは、制作したゲームを紹介します。
この記事は多少のネタバレを含むため、まだ遊んでいない場合は実際に遊んでから、記事を読み進めていただくことを推奨します。
選択肢を選んで主人公を出社させるという内容のノベルゲームで、1回3分程で気軽に遊べます。
このゲームは、13種類のエンディングが存在するマルチエンディングシステムとなっています。


制作スタッフ

ちよリ ※このゲームのモデルとなった人
役割 : プランナー兼デザイナー (シナリオ分岐設計・キャラ&タイトル画面のデザインを担当)
X : https://twitter.com/chiyorin_htrk

始めたばかりのたかし ※この記事を書いている人
役割 : アートディレクター兼プログラマー (画像や音声等の素材選定・Unity実装全般を担当)
X : https://twitter.com/BeginKashi


事前準備

公開場所の決定

ゲームを公開する場所は、unityroom にしました。
Unityで制作したゲームを無料で投稿&遊べるサイトです。
たくさんのゲームが投稿されていて1日遊んでいられます。
「Unityで作ったゲームをブラウザにアップすると言えばこの場所!」と多くの方がなるであろう言わずと知れた有名なサイトです。
1週間でお題に沿ったゲームを作って投稿する 1週間ゲームジャム という面白いイベントを定期開催していることでも知られています。

今回作ったゲームは、制作メンバーであり主人公のモデルとなった配信者ちよリさんの視聴者さんたちに気軽に遊んでもらいたという思いがあり、それならブラウザゲームだろう。それならunityroomだろう。
ということになり、初めて利用させていただきました。

ちなみにunityroomは、ないちさん という個人の方が開発・運用されています。
個人の方と言っても ないちさんは、初代Unityアンバサダー (※Unityの普及やコミュニティの発展に寄与する方々を称える制度) としてUnity公式から認められている方です。

作るゲームの情報整理

  • 分岐図の作成
    まず、このノベルゲームではどんなセリフが表示されて、どんな選択肢を選ぶとどう分岐するかを図で表します。
    こちらは、制作メンバーのちよリさんが作成してくださいました。
    どのタイミングでキャラ絵が切り替わるかも記載されていてとても分かりやすかったです。
    ネタバレ防止のため一部だけ載せます。

ゲーム序盤の分岐部分
  • 画面遷移図の作成
    分岐図をもとに、このゲームはどんな画面があってどのように遷移するかを図に表した画面遷移図を作りました。
    画面遷移図をどのくらい詳細に書くかは作るものによって異なりますが、今回は画面内に必要な要素と全体の流れが整理できればよかったので、この程度の粒度で作成しました。

※制作中に上記から変更になった箇所もあります
  • 使用素材リストの作成
    このゲームが完成するために必要な素材は何があるかを明確にするため、必要な音や画像などをリストに書き出します。
    使用するデータが決まったら、都度書き込んで埋めていきます。
    今回は特に、フリーで素材を配布してくださってる複数のサイト様を利用しているため、サイトごとに異なる利用規約を管理しておくためにも必要でした。

※上記は使用素材が決定し、全て記入したあとの最終的な状態です
  • 作業項目リストの作成
    完成までに必要な作業の項目を書き出します。
    今回の場合、ざっくり言うと以下のようなものがありました。
    ・表示される文章の文字送りと分岐の仕組みを実装
    ・X(旧:Twitter)に結果を投稿する機能を実装
    ・使用素材(音や背景等)の選定と実装
    ・タイトル画面デザインと実装
    ・結果画面の演出と実装
    ・アップロード作業
    ・デバッグ作業
    ・修正作業


仕組み部分の制作

ノベルゲームの仕組みを実装

まずは、このゲームのメインである「クリックして次のセリフを表示→選択肢を選んで分岐する」という部分を作ります。
今回のような選択肢によって分岐するような仕組みを一から作ると、コードを書く必要もありますし時間もかかります。

演出部分もあるのであまり時間をかけたくな早めに作り終えたかっため、Unityで使えるノベルゲーム制作ツール「Fungus」を使用しました。
Unityで使えるノベルゲーム制作ツールは調べるといくつかあり、  や Naninovel が有名ですが、Fungusは無料で使えるという点に惹かれて選びました。

ただ、こちらは海外で作られたツールなので公式ドキュメントも英語です。そのため、まずはこちらの日本語のわかりやすい解説動画を参考にさせていただきました。
この動画だけで、使い方がなんとなくわかりました。

動画を参考に「キャラクターが出てくる→セリフの表示→選択肢の表示」を作ってみました。

Fungusでの実装部分
プレイするとこうなります

ここまで1文字もコードを書かずに作ることができました。
ちなみにFungusでは、セリフを表示するなどの命令をコマンド(Command)、そのコマンドのひと固まりをブロック(Block)、ブロックが繋がった全体をフローチャート(Flowchart)と呼びます。
流れとしては、まず最初のブロック内のコマンドが順番に実行されていき、選択肢を選んで分岐すると別のブロックに繋がるという流れです。
移動先のブロック内のコマンドもまた順番に実行されていきます。

他にもFungusは、音の再生や背景切り替えなどノベルゲームに必要なことができるコマンドが多く用意されていて、簡単なノベルゲームならノーコードで全てを実装できます。
とはいえ、いろんな演出のコマンドを追加していった結果、初期段階の上図では6個のコマンドしか使用していなかった最初のブロックは、最終的に22個のコマンドを使用しました。
簡単に作れるとはいえ、よく考えて作らないとめちゃくちゃになりそうです。

また、Fungusのメリットとして、それぞれの処理の固まりを線で繋げて行く、いわゆるノードベースの作り方なので、フローチャートが組み上がっていくと最初に作成した分岐図と似た形になり実装漏れがないか見比べることもできます。

詳細な使い方を説明すると長くなってしまうので、参考にさせていただいたFungusをわかりやすく解説してくださっているサイト様を載せておきます。


X(旧Twitter)に結果を投稿する機能を実装

分岐図を確認すると、各分岐の最後には「二度寝エンド」「ふて寝エンド」といった特徴的な名前がそれぞれ添えられていました。

分岐図の一部抜粋

せっかくなので、エンディング画面に表示することにしました。
また、その結果をX(旧Twitter)に投稿できるようにしました。
遊んだあとに、遊んだ人同士で「そんなエンディングもあったの!?」なんて会話が生まれたらいいなという思いからです。
Xでたまに流行る診断ゲームの結果を投稿するようなノリです。

投稿機能に使用したツールは、unityroom-tweet です。
unityroomの開発・運用をしているないちさんが公開しています。
特定のボタンを押すなど呼び出したい場所で、このようなコードを1行書くことでゲームのリンク付きツイートを簡単に実装できるようにしてくださっています。

naichilab.UnityRoomTweet.Tweet ("unityroom内で設定するid", "ツイート内容");

しかし、今回は投稿の文章に各分岐のエンディング内容を入れたかったので、別途以下のような処理を追加することで実現しました。

Fungusで組んだ各分岐の最後で、Call Methodコマンドを追加します。
※任意の関数を呼び出すことができるコマンドです。

「Target Object」に作成したスクリプトがアタッチされたオブジェクト、「Method Name」にそのスクリプト内の呼びたい関数をそれぞれ指定します。

コードを以下のように記述しました。
上記で「Method Name」に指定した関数である「SetEndType_Nidone」で、まず「endType」という投稿する文章で使用している変数に、この分岐の結果を入れます。
また、画面の文字に結果を反映させる関数「SetTextEndType」にも結果を渡しています。

    // エンドタイプ投稿内容文字
    private string endType = null;
    // エンドタイプ結果画面文字
    [SerializeField] private Text textEndType;

    // 投稿 ※結果画面の投稿ボタンを押すことで呼び出されます
    public void OnClickedPostButton()
    {
        // https://github.com/naichilab/unityroom-tweet?tab=readme-ov-file
        naichilab.UnityRoomTweet.Tweet("shusshashirochiyorin", "#出社しろチヨリン で遊んだよ。結果は..." + endType);
    }

    // 結果内容をセット ※各分岐の最後でCallMethodコマンドから呼び出されます
    public void SetEndType_Nidone()
    {
        // 結果内容を変数にセット
        endType = "二度寝エンド😴";
        // 結果画面に表示される文字に反映
        textEndType.text = "二度寝エンド";
    }

UnityEventのようにCall Methodコマンドで関数を指定する際に引数を渡すことができればよかったのですが、そのような方法がFungusでは見当たらずこの方法で実装しました。
そのため、他の分岐のエンディングでも同様に「SetEndType_ + エンド名」といった関数を作成して呼ぶことで結果内容をスクリプトに渡しています。

以上の実装をし、プレイした動画がこちらです。

ちゃんと、画面の文字にも投稿の文字にも同じエンディング結果内容が反映されていることが確認できます。


結果演出の実装

上記で結果画面の大枠の仕組みは実装できたのですが、ただ結果の名前を表示するだけではあまり面白くないので、演出を工夫しました。
具体的には、「出社できた場合」と「出社できなかった場合」で文字の見た目・動き・音・エフェクトを大きく変えています。

出社できた場合
出社できなかった場合
  • 文字の色の切り替え
    〇〇エンドの文字は「出社できた場合」は暖色で明るいオレンジ系の文字で、「出社できなかった場合」は寒色の寂しげなブルー系の文字にしました。
    画像ではなくUIのTextで実装しています。
    インスペクターで設定した文字上部の色・下部の色・アウトラインの色を結果ごとにコードから変更しています。

    // 色変更対象
    [Header("変更対象")]
    [SerializeField] private GradationController gradationController;
    [SerializeField] private Outline outline;

    // 色
    [Header("変更色")]
    [SerializeField] private Color colorSucessTop = Color.white;
    [SerializeField] private Color colorSucessBottom = Color.white;
    [SerializeField] private Color colorSucessOutline = Color.white;
    [SerializeField] private Color colorFailedTop = Color.white;
    [SerializeField] private Color colorFailedBottom = Color.white;
    [SerializeField] private Color colorFailedOutline = Color.white;

    // 色をセット
    private void SetTextColor(bool isSuccess)
    {
        gradationController.colorTop = isSuccess ? colorSucessTop : colorFailedTop;
        gradationController.colorBottom = isSuccess ? colorSucessBottom : colorFailedBottom;
        outline.effectColor = isSuccess ? colorSucessOutline : colorFailedOutline;
    }
  • 文字の動き
    文字の動きは「出社できた場合」は飛び出すような元気な動きで、「出社できなかった場合」はゆらゆらと元気のなさそうな動きをそれぞれアニメーションで作成して、結果によってコードから切り替えを行なっています。

    // Animator
    [SerializeField] private Animator animatorEndTypeText;

    // アニメをセット
    private void SetTextAnim(bool isSuccess)
    {
        animatorEndTypeText.SetTrigger(isSuccess ? "success" : "failed");
    }
  • クリア時のエフェクト
    キャラを出社させるというゲームの都合上、クリアした場合はキャラが画面外に移動して消えるため逆にクリアした方が画面が寂しくなってしまいました。

エフェクトがない場合

そこで「出社できた場合」のみエフェクトを発生させています。
エフェクトを追加したことで結果として、画面が賑やかになりクリアした達成感を感じられるようにもなりました。

エフェクトがある場合

エフェクトは、Unityのパーティクルで実装して画面上部から発生させています。
それをFungusのSet Activeコマンドを使用して表示させています。

パーティクルの設定は単純で、「Start Color(発生時の色)」を「Random Color(グラデーションからランダムな色)」に設定してグラデーションを作成して、「Velocity over Lifetime(生存期間中の速度)」と「Rotation over Lifetime(生存期間中の角度)」を使用して風に揺られる動きを作っています。


操作に反応するボタンの実装

ゲーム内の各ボタンは、マウスカーソルやスマートフォンで指が重なると見た目が切り替わるなど、ユーザーの操作に反応する仕組みを実装しました。
細い部分ではありますが、操作できている安心感を生み出し、なにより触っていて楽しいゲームになると思うので地味に大事なことだと思っています。

例えば、電子マネーWAONのカードでお支払いすると、レジで「ワオン!」と元気な犬の声が鳴って毎回恥ずかしいですが、もしこれがなくなった場合は反応してるか不安になるしちょっと寂しくなると思います。

以下が、このゲームでの具体例と実装方法です。

  • ゲームスタートボタン
    操作がない時は、ここを押してねとふわふわと動き続けます。
    カーソルと重なると、音の再生と共にボタンの色が濃く変化します。
    押すと、音の再生と共に物理的に押されたかのように沈みこみます。

※音はgifなので出ません。音は実際にプレイして確かめてください。

実装方法はコードは書かずに、発生させたいイベントを指定できる「Event Trigger」コンポーネントを使用しました。
「Pointer Enter(重なった)」で音の再生をするように指定し、「Pointer Up(押している状態から離した)」で音の再生とアニメーションの再生をするように指定しています。

  • 選択メニュー
    カーソルと重なると、音の再生と共にボタンの画像が切り替わります。
    押すと、音の再生がされます。

実装方法は、同様に「Event Trigger」コンポーネントを使用しました。
「Pointer Enter」と「Pointer Up」で音の再生をするように指定しています。
画像の切り替えは「Button」コンポーネントの「Transition(遷移)」を「Sprite Swap(画像の切り替え)」にして「Highlight Sprite(重なった時に切り替える画像を指定するとこ)」に切り替えたい画像を指定しています。


オススメの素材サイトを紹介

上述の事前準備でも書きましたが、フリーで素材を配布してくださってるサイト様をいくつか利用させていただいています。
その中でもおすすめのサイト様を素材の種類ごとに紹介します。

  • 背景素材

ノベルゲーム用の背景を探すとファンタジー色が強いものが多いのですが、こちらのサイト様は現実的な背景が多くて助かりました。
また一つの背景に対して、日中や夕方など時間による差分の画像まで用意されていてノベルゲームでは重宝します。
最近流行りの猫ミーム動画でも使われているのを見かけました。

  • フォント

オープンソースのフリーフォントをまとめてくださっています。
ポップめなフォントが多いです。

  • UI

様々なデザインのメッセージウインドウと選択メニューの素材を配布してくださっています。

ちなみに、使用したメッセージウインドウには左上にキャラ名の入るスペースが用意されていました。

複数のキャラクターが会話するようなノベルゲームだと使いますが、今回は登場するキャラクターが1人のみだったので画像編集して消してから使用しました。

他にもいくつかの画像素材は、ゲームの雰囲気に合うように編集してから使用するという一手間を加えています。
※改変をする際は規約を確認しましょう。

これらの素材を入れ込むと・・

紹介させていただいたこれらのフォントや画像素材を入れ込んだら、ゲームの見た目がどのくらい変わったかの比較をお見せします。
どちらも同じゲーム冒頭のキャラ登場から選択肢の表示までのシーンです。

素材入れ込み前

素材入れ込み前は、シンプルな画面でどこかクイズゲームのような雰囲気を感じます。

素材入れ込み後

一方で素材入れ込み後は、フォントや選択メニューのUI素材のおかげで全体的に可愛らしい雰囲気のゲームになりました。また、背景画像のおかげで主人公のいる場所やシチュエーションが視覚的にわかります。上記はgifなので音は出ませんが、実際はチュンチュンと鳴くスズメの音も入れており、朝の穏やかな空気感まで感じられるようになりました。


ゲームをアップロード

unityroomへのアップロード方法ですが、こちらに関しても開発・運用されている、ないちさんが以下のサイトでわかりやすく手順を説明してくださっていました。

その中から、アイコン設定と公開設定に関して詳しく説明します。

  • アイコン設定
    ゲームのアイコンは、静止画またはgifが設定できます。
    ゲームの一覧が並ぶunityroomのホーム画面で、動いているアイコンの方が目を惹かれると感じたためgifのアイコンにしました。

    ノベルゲームの一番の醍醐味でもある選択肢を選ぶ部分をアイコンにしようと思ったのですが、アイコンは1:1の比率だったため、横画面のノベルゲームから切り取ってアイコンにするとどうしても選択メニューの両端が見切れてしまいました。

そのため、アイコンでは選択メニューのサイズを調整して、このゲームの魅力が伝わるように1:1の比率に綺麗に収めました。

完成したアイコン

このように、作るゲームによってはアイコンに収める作業が必要になるかもしれません。

  • 公開設定
    非公開と公開だけではなく、YouTubeのようにリンクを知っている人のみアクセス可能な限定公開が用意されています。
    公開前に制作メンバーに共有したり誰かにデバッグしてもらう場合にとても便利です。

unityroomのゲーム登録画面より


まとめ

ざっくりではありますが、制作工程や実装方法などを順を追って紹介してきました。
ノベルゲームを作ったことも初めてでしたが、noteで記事を書いたことも初めてでした。読みにくい点もあったとは思いますが、ここまで読んでくださりありがとうございます。

この記事の執筆時点ではまだゲームは公開していませんが、共同制作者のちよリさんのおかげもあって、全体的に可愛く素敵なゲームに仕上がったため既に満足しています。
とはいえ、自分が作ったものに反応があると嬉しいので、ぜひゲームを遊んで感想や投稿をいただけると幸いです。

Unityで作成した作品を不特定多数の人が遊べる場所に投稿する経験は、これまでにメタバースプラットフォームclusterのワールド制作のみでした。
そのため、今回は同じく投稿できるunityroomにも挑戦できたことも初めてで貴重な経験になりました。
今後も、個人的に面白いゲームが思いついたら投稿しようと思います。


この記事が参加している募集

ゲームの作り方

この記事が気に入ったらサポートをしてみませんか?