ASP.NET Core を使ってREST APIを作ってみる

ASP.NET Core を使ってREST APIを作ってみる

執筆者:みやじ

これは OUCC Advent Calendar 2022 の17日目の記事です。
ここではTodoアプリのバックエンドを想定して簡単な REST APIを作ってみようと思います

目次

プロジェクトを作る

Visual Studioで ASP.NET Core Web API のプロジェクトテンプレートを選択して作成します。
実行するとhttps://localhost:<port>/swagger/index.htmlが自動的に開き最初からある WeatherForecast API が表示されます。ここで<port>ランダムに選択されたポート番号です。よく見るSwaggerページだと思います。Try it out で試しに実行することもできます。

サンプルデータ用のサービスを作成する

まず次のようなTodoItemクラスを作成します。

public class TodoItem
{
    public int Id { get; set; }
    public string? Title { get; set; }
    public string? Description { get; set; }
    public DateTime DueDate { get; set; }
}

つぎにそれを扱うITodoItemContainerを作ります。実装は少し長くなったので下の方に書いておきます。単純にList<TodoItem>を用意してそれに足したり抜いたりしているだけです。

public interface ITodoItemContainer
{
    IEnumerable<TodoItem> GetTodoItems();
    TodoItem? AddTodoItem(TodoItem item);
    bool RemoveTodoItem(int id);
    bool UpdateTodoItem(TodoItem item);
}

ASP.NET Core は依存性注入(DI)を採用しているのでITodoItemContainerを API Controller で使うためにはDIコンテナに登録する必要があります。 Program.cs でbuilder.Build();が呼び出されている箇所より上でbuilder.Services.AddSingletonを呼び出せば登録することができます。
今回は次のコードをを追加しました。

builder.Services.AddSingleton<ITodoItemContainer, TodoItemContainer>();

API コントローラーの作成

API コントローラーはControllerBaseを継承して作ります。これを継承することで応答に便利な関数を利用できます。

[ApiController]
public class TodoItemsController : ControllerBase

ApiCotroller属性をつけると以下のようなAPIの動作を有効化できます。

  • 属性ルーティング要件
  • 自動的な HTTP 400 応答
  • バインディング ソース パラメーター推論
  • マルチパート/フォーム データ要求の推論
  • エラー状態コードに関する問題の詳細

以下のように API コントローラーにメソッドを定義することでアクションを設定できます。ApiController属性を付けているとHttpGet属性なしでもメソッド名にGET POST PUT DELETEが含まれていると自動的にHTTPメソッドとして登録されますが、Swaggerが認識できないのでHttpGet属性をつけるほうが良いです。

[HttpGet]
public ActionResult<TodoItem> GetTodo() { }

ルーティング

ルーティングはRoute属性を用いてコントローラーまたはアクションに設定できます。ASP.NET Core のルーティングは大文字小文字の区別がありません。api/todoでもApi/Todoでも同じものとして扱われます。
コントローラにRoute属性を使うとそのコントローラーでのデフォルトのルートが設定されます。[controller]はコントローラーの名前から自動的に Controller の部分を取り除いた文字列が入れられます。
アクション、つまりメソッドにRoute属性を使うとそのメソッドだけにルーティングを設定できます。このとき、/または~/で始めるとコントローラーのルートテンプレートと結合されません。

また HttpGet などの HTTP 動詞テンプレートでもルーティングは設定できます。 HTTP 動詞テンプレートを使うとその HTTP 動詞だけを受け付けるように制限されるので REST API を作るなら全て HTTP 動詞テンプレートを使うこと方が良いです。 HTTP 動詞テンプレートは以下の6つです。

  • [HttpGet]
  • [HttpPost]
  • [HttpPut]
  • [HttpDelete]
  • [HttpHead]
  • [HttpPatch]
[Route("api/[controller]")]
[ApiController]
public class TodoItemController : ControllerBase
{
    [HttpGet]          // api/TodoItem
    public ActionResult<TodoItem> GetTodo() { } 

    [HttpGet]
    [Route("todo")]    // api/TodoItem/todo
    public ActionResult<TodoItem> GetTodo() { }

    [HttpGet("todo")]  // api/TodoItem/todo
    public ActionResult<TodoItem> GetTodo() { }

    [HttpGet("/todo")] // todo
    public ActionResult<TodoItem> GetTodo() { }
}

メソッドの引数

メソッドの引数はURLパスから受け取ったりリクエスト本文から受け取ったりできます。

URLパスから情報を受け取る

Route属性やHttpGet属性などで{id}のように書くことで、引数idにその値を受け取ることができます。また、{id?}とすることで省略することができます。省略された場合引数にはデフォルトの値が入ります。

[Route("api/[controller]")]
[ApiController]
public class TodoItemController : ControllerBase
{
    // api/TodoItem/1 => id = 1
    // api/TodoItem   => id = 0
    [HttpGet("{id?}")]
    public ActionResult<TodoItem> GetTodo(int id) { }
}

URLクエリパラメータやリクエスト本文から受け取る

それぞれ以下の属性を引数につけることでリクエストから受け取ることができます

  • FromQuery リクエストのクエリパラメーター
  • FromBody リクエスト本文
  • FromForm リクエスト本文内のフォームデータ
  • FromHeader リクエストヘッダー

FromBodyはSystem.Text.Jsonを使って自動的にパースしてくれます。

[Route("api/[controller]")]
[ApiController]
public class TodoItemController : ControllerBase
{
    [HttpPost]
    public ActionResult<TodoItem> CreateTodo([FromQuery] int id, [FromQuery] string title) { }

    [HttpPost]
    public ActionResult<TodoItem> CreateTodo([FromBody] TodoItem todo) { }
}

メソッドの返り値

メソッドの返り値にはActionResult<T>を指定しておけば暗黙的なT=>ActionResult<T>のキャストが実装されているのでとりあえずは困らにと思います。型が指定できないとき、例えば匿名型を使用するときなどはActionResultを使えばよいです。
そのまま値を返しても問題ありませんが、ControllerBaseに実装されているメソッドを利用することで一緒にStatusCodeを指定することもできます。よく使われそうなものをいかに列挙しておきます。

  • Ok(Object)
    HTTP 200 OK を返すオブジェクトを生成する。
    引数にはアクションの返り値にしたいオブジェクトを指定する。
  • Created(String, Object)
    HTTP 201 Created を返すオブジェクトを生成する。
    第1引数にはコンテンツが作成された URI を、第2引数にはアクションの返り値にしたいオブジェクトを指定する。
  • CreatedAtRoute(String, Object, Object)
    HTTP 201 Created を返すオブジェクトを生成する。
    第1引数には作成されたコンテンツを返すアクションの名前を、第2引数にはそのアクションのURLの生成に使用するルートデータ。第3引数にはアクションの返り値にしたいオブジェクトを指定する。
  • NotFound()
    HTTP 404 Not Found を返すオブジェクトを生成する。

もっと見る場合は ControllerBase クラスのドキュメントを参照してください。

[Route("api/[controller]")]
[ApiController]
public class TodoItemController : ControllerBase
{
    private ITodoItemContainer _todoItemContainer;

    public TodoItemController(ITodoItemContainer todoItemContainer) {
        _todoItemContainer = todoItemContainer;
    }

    [HttpGet("{id}")]
    public ActionResult<TodoItem> GetTodo(int id) {
        var todo = _todoItemContainer.GetTodoItems().FirstOrDefault(t => t.Id == id);
        return todo is null ? NotFound() : Ok(todo);
    }

    [HttpPost]
    public ActionResult<TodoItem> AddTodo([FromBody] TodoItem item) {
        var todo = _todoItemContainer.AddTodoItem(item);
        return todo is null ? BadRequest() : CreatedAtAction(nameof(GetTodo), new { Id = todo.Id }, todo);
    }
}

完成

他にPUT DELETEメソッドを追加して最終的に次のようになりました。

TodoItemControllerの実装

[Route("api/[controller]")]
[ApiController]
public class TodoItemController : ControllerBase
{
    private ITodoItemContainer _todoItemContainer;

    public TodoItemController(ITodoItemContainer todoItemContainer) {
        _todoItemContainer = todoItemContainer;
    }

    [HttpGet]
    public ActionResult<TodoItem[]> GetTodoList() {
        return Ok(_todoItemContainer.GetTodoItems().ToArray());
    }

    [HttpGet("{id}")]
    public ActionResult<TodoItem> GetTodo(int id) {
        var todo = _todoItemContainer.GetTodoItems().FirstOrDefault(t => t.Id == id);
        return todo is null ? NotFound() : Ok(todo);
    }

    [HttpPost]
    public ActionResult<TodoItem> AddTodo([FromBody] TodoItem item) {
        var todo = _todoItemContainer.AddTodoItem(item);
        return todo is null ? BadRequest() : CreatedAtAction(nameof(GetTodo), new { Id = todo.Id }, todo);
    }

    [HttpPut]
    public ActionResult<TodoItem> UpdateTodo([FromBody] TodoItem item) {
        var result = _todoItemContainer.UpdateTodoItem(item);
        return result ? Ok(item) : BadRequest();
    }

    [HttpDelete("{id}")]
    public ActionResult DeleteTodo(int id) {
        var result = _todoItemContainer.RemoveTodoItem(id);
        return result ? NoContent() : BadRequest();
    }
}

ITodoItemContainerの実装

public class TodoItemContainer : ITodoItemContainer
{
    private List<TodoItem> _items;

    public TodoItemContainer() {
        _items = Enumerable.Range(1, 10)
            .Select(i => new TodoItem {
                Id = i,
                Title = $"todo item id:{i}",
                DueDate = DateTime.Today.AddDays(1)
            }).ToList();
    }

    public IEnumerable<TodoItem> GetTodoItems() => _items;

    public TodoItem? AddTodoItem(TodoItem item) {
        if (item.Id >= 1 && _items.Any(t => t.Id == item.Id))
            return null;

        if (item.Id < 1)
            item.Id = _items.Max(t => t.Id) + 1;
        _items.Add(item);
        return item;
    }

    public bool RemoveTodoItem(int id) {
        var todo = _items.FirstOrDefault(t => t.Id == id);
        return todo is not null && _items.Remove(todo);
    }

    public bool UpdateTodoItem(TodoItem item) {
        var todo = _items.FirstOrDefault(t => t.Id == item.Id);
        if (todo is null)
            return false;

        _items[_items.IndexOf(todo)] = item;
        return true;
    }
}

あとがき

HTTP Status Code がどれを使えばいいのか全然わからなかったです。加えてうまくSwaggerに反映されてくれなくてよくわからなかったです...

参考

音MADの話

執筆者: ちょくぽ

これは OUCC Advent Calendar 2022 の 12/9 の記事です。
記事中の〇はただの検索避けです

音MADをつくろう

音MADを作る動機はファンアートなどと同じですが、音MADに使われる技術は他のことにも使えます。基本的にDAWとvocalshifterの技術なので。

  • 合成音声に歌わせる・変な声を出させる
  • 歌の調整をする(人間でも合成音声でも)
  • 普通の動画で音ハメ

などなど……

前提

Q. 音MADって著作権的にどうなの?
A. 元ネタ(素材)の作者に訴えられた場合、確実に負けます。
音MADを作るなら、著作権者に目を付けられないよう、黙認されるよう常に心がけましょう。(要するに二次創作と同じ)

Q. 音MADって儲かるの?
A. 商用利用が許可されている素材だけで作れば広告を付けることはできますが、それが面白くなる確率はかなり低いです。そもそも儲けようと思わない方がいいです。著作権的にも。

Q. 消されないの?
A. 消されます。よっぽどでない限り動画削除だけで済ませてくれますが……

原作者や他のMAD製作者への、可能な限りのリスペクトor配慮をしましょう。
二次創作界の空気感としてもそういう所は特に大事です。というかどの界隈でも発信をするなら半年ROMれ。

海外のフェアユースの思考は日本の感覚とかけ離れているので参考にしてはダメです

音MADの技術の情報はどこで手に入る?

音MADでググるのも良いですが、ニ〇二コだと音楽+コメント付きなので情報が多いです(経験談)。素材はほとんど淫〇ですが。
というか、音MAD自体サムいネタで遊ぶのがメインのような界隈です。勘違いしないように

淫〇や2〇兄貴周りは面白い情報がちょくちょくあります
2〇式動画講座が有能すぎ
純粋な作曲に関する情報も、当然役に立つのでありです

素材集め

素材を集めます。

  1. 原曲
    MADの原曲となる曲を探して、必要な長さのmp3やmp4を入手します。ボカロなどは作者が配布しているケースがありますが、すべての音を手元で作ればかっこいい……(地獄)。

  2. 音声素材
    MADの楽器の音やボーカルにするために、素材を集めます。楽器にするならキャラクターの声質や音圧を重視し、環境音をドラムにしましょう。
    キャラクターに歌わせたいなら、一文字一文字あつめるのが一番早い。歌詞をガン無視して面白いセリフを音合わせする方が楽。

  3. 動画素材
    音MAD制作は音作りがすべてではありません。原作に寄せた動画素材を集めたり、MP4を透過したり……同じジャンルのMAD動画も参考にしましょう。手描きは自信があれば。

二次創作を許可しているコンテンツは探せばかなり多いです。
実際によく使われている素材は、BB配布素材のように権利者に削除する気がないもの、権利者がtwitterでMAD動画に言及しているものなど、セーフ寄りのグレーがほとんどですが……
(ニ〇二コで流行っている例のアレの多くは許可されているわけではないので注意)

ツール

  • REAPER
    DAWならなんでもいいですが、REAPERがおすすめです。有料として紹介されることが多いですが、普通に無料で使えます。

  • VocalShifter
    音声が一定の音程になるよう調整し、素材にできる。音の外しや調子など細かな調整もできる。

  • Wavetone
    テンポ測定や耳コピが必要なら。

  • 動画編集ソフト
    Aviutlなんてソフトは過去の産物なので、普通に最近出たソフトを使いましょう。私はAviutl使います。どれも機能はだいたい一緒です。

メイン

REAPERの操作は覚えれば便利な操作が書ききれないほどあるので、適宜調べてください
file

web上の適当なオンラインBPM計測などで音楽に合わせてクリックしてテンポを解析したら、REAPERに設定します。

原曲(写真上)をREAPERにドロップすれば、グリッド線がなんとなく波形に合います。

REAPER上ではマウスの他に Alt+ドラッグ、S、ctrl+shift+n、ctrl+D、F2、Alt+S などの操作をよく使います。適当に試して体で覚えましょう。

file

素材を母音などで分割し、音楽に合うように配置(大抵の場合、八分音符より細かい調整は必要ないです)
原曲の力を借りているので当然、これだけでMADとして聞けるレベルになります。実際、分割と配置のみでランキング上位になるような音MADも多いです。

エフェクト(ここではVST)でリバーブを付ける、パン(FXの左のつまみ)をトラックごとに左右にずらすなどすると聞きやすくなります

file

次に、音程を変えてみましょう
vocalshifterに素材を渡して素材をダブルクリックすると、ピッチ補正ができます。
黄色い線でピッチを平坦にすれば、音程を変えやすい素材として利用できます。黄色い線(今はD4)がこの音声の音程なので、覚えておきます。

file

これで作成したピッチ調整済wavファイルをREAPERに持っていきます。複数アイテムを選択してF2から一括でwavファイルを変更できます。

アイテムを選択してShift+0、Shift+9で音程を1ずつ変えられるので、MIDIファイルや楽譜、WaveToneなどとvocalshifterの黄色い線を見比べながら調整しましょう。単純作業です。
file

これができたら音作りはできたも同然です。
細かい技術は最初から調べるのではなく、とりあえず触ってから学んだ方が意欲も学習速度も上がります。

場所によって黄色の線を数音高くしたり低くすることでビブラートや感情をつけられます。
クオリティ高い音MADでは、次の手順を踏むものが割とあります。

  • vocalshifterで平坦にした声をREAPERで並べ、切り貼りタイミング合わせだけする
  • それを再度vocalshifterに戻し、音程をつける
  • 音程が大きく飛ぶところではしゃくりや裏返り、伸ばすところではビブラートなどをつける

スケールを外すと目立ちすぎるので、外すときの音は考えましょう。(これ以上は音楽理論の話)

Aviutlの編集は割愛しますが、BPMを指定してグリッド線を小説ごとにする設定項目があります。活用しましょう。
音が鳴るたびに素材を左右反転させる、ちょっとだけ大きくして跳ねさせる、などすると視覚的に楽しくなります。
あとイージングを親の仇のように多用しましょう。
モーショングラフィックス関連のプラグインも沢山あるので、Aviutlで何かを始めるときは即座にプラグインを検索しましょう。

おわりに

いかなる創作においても、数字を見るのはやめましょう。作るのが楽しいのです。
数字は作品のクオリティとは関係なく、題材と宣伝が全てです。マジで。

OUCC Advent Calendar 2022

次回のアドベントカレンダーは12/11、Ayaka氏です!

3Dモデルの調整をしながらVRChat用モデルからVRMへ効率良く変換する

Blenderで制作して完成したと思っても、実際に動かしてみたりするとウェイトペイントが上手くいってなくて服が突き抜けたり、テキスチャがおかしかったりと、様々な問題が発生してBlenderでの修正を再三に迫られる場面は多いです。
そのためにBlender側で修正したものを出力してUnityに読み込ませます。そのUnityへ読み込ませる際にちょっとした工夫をすると作業量を緩和できます。

この記事は多分OUCCアドベントカレンダーの最終日の記事になります。

プロローグは暇な人だけ読んでね

それ以外の人は本題

~プロローグ?~

~3Dモデル制作以前

去年のハッカソンでは、何かと不満を言われるE-Learningと和解しようという企画にて、自然言語で会話できるBotを制作しました。
その過程で会話相手として、E-Learningの化身、angEL-reinちゃん(名前はE-Learningのアナグラムから)が生まれました。私が生みました(生産者表示)
この名前微塵も流行らず、代わりにいーちゃんと呼ばれているのですが、このいーちゃんを音声で入出力して会話できるようにして学祭に出そうという話になりました。
そこで私はRustサーバーを作って非常に遅い言語生成処理の高速化を行ったりしたわけですが、そんな話は今回どうでも良く、それよりやはり音声での会話をするならば、会話する相手が見えた方がいいですよね?古来より偶像崇拝があるように概念を相手にするよりかは、視覚的に見えるものを相手にした方が良いに違いない。
というわけで、れいんちゃんの3D化計画を極秘裏に進めました。
以前の記事で既にLive2D化した話はしましたが、我慢できずに3D化に踏み切ってしまいました。

3Dモデル完成(仮)まで

まずVROIDで素体を生成し、Blenderで服などを制作しました。
私は3Dモデルを作るのはこれで2回目なので初めてというわけでは無いですが、やはりそれなりに苦戦はしました。特に前回と同様ウェイトペイントでは常に苦戦させられ、今回も最後まで難敵となりました。
まあ兎に角色々あってFBXモデルが完成しました。
VRChatに出したかったのでまずVRChat用の改変をしつつシェーダの調節をしていきました。
その結果完成したのがこちら
れいんちゃん
れいんちゃん
れいんちゃん
ちなみに私は目にこだわる人なので、目は虹彩を奥に配置し、反射光を前面に出すなど立体的にしています

その後単眼カメラによる姿勢推定アプリを制作する、又はキャラクタを後世の人に使ってもらうためにVRMモデルへの変換を行いました。

本題

 Blenderで制作して完成したと思っても、実際に動かしてみたりするとウェイトペイントが上手くいってなくて服が突き抜けたり、頂点にウェイトが割り当てられてなかったり、テキスチャがおかしかったりと、様々な問題が発生してBlenderでの修正を再三に迫られる場面は多いです。
 そのためにBlender側ではLazy Weight Toolなどを使って個々の頂点についてウェイトを塗りなおしたりして修正したものを出力してUnityに読み込ませます。そのUnityへ読み込ませる際にちょっとした工夫をすると作業量を緩和できます。

fbxファイルのBlender→Unity

 fbxファイルをunityに読み込むと、モデルをScene上に配置できるようになります。
VRChatを想定した場合、その配置したモデルにPhysboneなどのコンポーネントを設定していくことになります。
 しかしこの方式では、後で修正をかけたモデルで上書きして読み込む際にfbxファイルと共にScene上のオブジェクトもリセットされてしまい、またコンポーネントの設置などをしなければならなくなります。
 これでは非常に非効率なので、fbxファイルを上書きで読み込んだ際にScene上のオブジェクトのコンポーネントがはがれないようにしたいです。

 そんな時に便利なのがPrefab Variantです。
 Projectビューからfbxファイルを右クリック→Create→Prefab Variantで生成できます。
 この生成したものをドラッグアンドドロップでSceneに配置してコンポーネントを張り付けてみてください。
 こうすることでfbxファイルを上書き更新しても、Scene上のモデルだけが更新され、コンポーネントは剥がれなくなります。

VRChatモデル→VRMモデル

基本的には VRM Converter for VRChatを使用しますのでこれを既にUnityへインポートしている前提で記述します。

初めてのexport

 まず変換するVRChatモデルを選択した状態でツールバーのVRM0→Export VRM file from VRChat avatarで適当に入力してAssetディレクトリ内に用意したフォルダ(フォルダ1)にexportします。
 この際もしかしたら未使用シェイプキーにチェックを入れてexportした方がいいかもしれません。
 兎に角これでフォルダ1内にVRMファイルとそのprefabが生成されます。エラーが出ても、何も変えずにもう一度実行すると何故かうまくいったりします。
 Unity上だけで表情やマテリアル、SpringBoneなどの設定を変更するくらいなら、そのPrefabをSceneに配置・編集して、そのモデルを選択した状態でツールバーVRM0→export to VRM0でフォルダ1に出力すると、フォルダ1のVRMを上書き修正することができます。

2回目以降のexport

  1.  モデルを変更した場合、またVRChatモデルからVRMへの変換をする必要があります。
     この変換においてVRM0→Export VRM file from VRChat avatarで出力する場所はフォルダ1とは異なるフォルダ2へ出力した方が良いです。
     何故なら、フォルダ1に出力してしまうとせっかく以前に設定した表情や物理などのコンポーネントが上書きされてしまうからです。
     この時、フォルダ1には旧、フォルダ2に新モデルが入っていることになります。

  2. 生成された新モデルのPrefabファイルをSceneにドラッグアンドドロップで配置。
  3.  ツールバーのVRM0→Open CopyVRMSetting Wizardで以前のデータからSpringBoneや表情などの情報を新モデルへコピーします。
     この時に、Sorceにはフォルダ1の旧Prefabアセット(Projectビュー上)を選択し、Destinationには新モデルオブジェクト(Sceneビュー上)を選択しないとエラーが出ます。
     ここまででコピーできていないのはマテリアルのみです。
  4.  マテリアル情報を新モデルにコピーしていくのですが、使用マテリアルが多ければ多いほどこの作業が非常に面倒です。
     よってそれをやってくれるツールを自作しました。
     ここ(https://github.com/sachsen/TransferInspectorMaterials) から.csファイルを入手して、readmeに書かれている通りに導入してください。
  5.  ツールバーTools→Open Inspector Material Transfer Windowとします。
     sizeにコピーするSkinnedMeshRendererの数を入力し、Sorceにコピー元の、Destinationにコピー先のSkinnedMeshRendererを指定してCopy!ボタンを押すとマテリアル情報がコピーされます。なお、マテリアル自身は複製されません。
  6.  新しいモデルを選択してツールバーVRM0→export to VRM0でフォルダ1へ出力、上書きします。
     これでVRMファイルが新しくなって置き換わります。

完成

3Dモデルはこちらからぐりぐり見れます。

https://hub.vroid.com/characters/7942564502413041514/models/2799418893141239533

文化祭での様子

もっといい方法があるかもしれないですが、私はこの方法でやりました。

よければお使いください。

著者:上月

Unityでノベルゲームを制作中

はじめに

この記事はOUCC Advent Calender 2019の23日目の記事です(完成したのは12/31です)

パワポケから野球要素を抜いたノベルゲームみたいなのを作りたかったので、12月から土台作りを始めました。
土台作りといっても基礎となる部分は以下のサイトを参考に作成しました。

今回はこれをパワポケ風に近づけるために追加した機能を書きたいと思います。

1 キャラの立ち位置を二か所にする

パワポケでは左右にキャラが立って、会話が展開されるので、まずはキャラを左右に立たせるようにしました。このとき、3人目のキャラを追加するときは、既にいるどちらか二人のうちの一人を消して、3人目のキャラを追加するようにしました。

Gif画像をUpしたかったのですが、容量的に上げられませんでした...

2 背景画像を変える

#bg_imageで背景を変えられるようにしました。

3 真ん中に画像が出るようにする

背景と同じ要領で真ん中に画像が出るようにしました。背景との違いは#center_imageで真ん中に画像が出現して、#center_image_offでその画像を見えなくするといったところです。

4 選択肢の内容をメッセージボックスに表示する

選択肢のボタンを表示させて、ボタンに触れるとそのボタンのテキストの内容をメッセージボックスに表示するようにしました。

5 その他機能

そのほかに追加した機能としては、BGMを変える機能や、SEを鳴らす機能、コマンドで使用している'#'をメッセージボックスに表示させるためのエスケープシーケンスを実装しました。

6 まとめ

以上述べたような機能を実装しましたが、パワポケ風にするためには、パラメーターの追加やフラグ管理など、追加しなければならないことが沢山あるのでこれからも追加していきたいと思います。
今回は容量の都合上、gif画像を使えなかったので、次に投稿するときはgif画像を上げられるようなブログで書きたいなと思います。

お借りした素材

キャラクターの素材:いらすとや様
背景素材:あやえも研究所様
出演:部室に侵入した猫様