🤖

はじめて作る UTAU プラグイン(開発チュートリアル)後編 (A)

2024/06/08に公開

つづき

中編では、UTAU プラグイン開発の準備を整えました。

後編では、いよいよ半音上げプラグインを作ります。

デザイン作成

中編で作り始めた HanonAge プロジェクトの続きで、半音上げプラグインの画面デザインを作りましょう。

デザインタブで、以下の写真のように Label を 1 つ、Button を 2 つ配置してください。やり方を忘れてしまった場合は前編をご覧ください。

Label のプロパティ

Label のプロパティを以下のように設定してください。

プロパティ
Text 選択された音符を半音上げます

半音上げプラグインはシンプルなプラグインなので説明を表示しなくても大丈夫とは思いますが、説明があったほうがユーザーに分かりやすいかと思います。

実行ボタンのプロパティ

実行ボタンのプロパティを以下のように設定してください。

プロパティ
Name ButtonGo
Text 実行

Name プロパティ(なぜか (Name) と括弧付きになっています)はその名の通りコントロールの名前です。

今回は Button が 2 つあるので、Name プロパティを付けて見分けやすいようにします。デフォルトでは button1、button2 のようになっており、そのままだと「どっちが実行ボタンだっけ?」というのが分かりづらいためです。

キャンセルボタンのプロパティ

キャンセルボタンのプロパティを以下のように設定してください。

プロパティ
Name ButtonCancel
Text キャンセル

フォームのプロパティ

デザインタブのウィンドウ内で、コントロールが配置されていない部分(タイトルバーでも構いません)をクリックすると、プロパティエリアにフォーム(ウィンドウ)のプロパティが表示されます。

フォームのプロパティを以下のように設定してください。

プロパティ
AcceptButton ButtonGo
CancelButton ButtonCancel
MaximizeBox False
MinimizeBox False
FormBorderStyle FixedSingle
Text 半音上げ

AcceptButton はデフォルトボタンのことで、ユーザーが単にエンターキーを押した場合は、ここで設定したボタン(つまり実行ボタン)がクリックされたことになります。

ユーザーが Esc キーを押した場合は、CancelButton で設定したボタン(つまりキャンセルボタン)がクリックされたことになります。

MaximizeBox MinimizeBox はウィンドウのタイトルバーに最大化ボタン・最小化ボタンを表示するかどうかです。半音上げプラグインではウィンドウサイズの変更は不要なので、両方とも False にしています。

プログラミングでは Yes / No に相当する語句が True / False となっていて、これを「真偽値」と呼びます。ニュアンスとしては「該当するのか、該当しないのか、どっちだ?」くらいの感じで、「True=真=該当する=Yes」、「False=偽=該当しない=No」くらいで捉えれば良いでしょう。

MaximizeBox(最大化ボタン)を表示するか?」を False にしているので、「No、表示しないよ」ということです。

FormBorderStyle を FixedSingle にしていますが、こうすることで、ユーザーはウィンドウの縁をドラッグしてリサイズすることができなくなります。MaximizeBox MinimizeBox FormBorderStyle の 3 つを設定することにより、ユーザーによるウィンドウリサイズを完全に封じています。

とはいっても、デザインタブ内で開発中は、ウィンドウの縁をドラッグしてリサイズ可能です。デザインタブ内のウィンドウをリサイズして、ちょうどいい大きさにしてください。

フォームの Text はウィンドウタイトルバーの文字になります。

デザインの確認

デザインを終えたら、いったん確認してみましょう。

Visual Studio の[ビルド → ソリューションのビルド]メニューで半音上げプラグインをビルドしてから、UTAU の[ツール → プラグイン → 半音上げ]メニューで半音上げプラグインを起動します。

まだプログラムコードを書いていないので、実行ボタンやキャンセルボタンをクリックしても何も起こりません。ウィンドウ右上の×ボタンをクリックして半音上げプラグインを終了します。

音符情報ファイルの内容表示

いよいよ動作の中身を書いていきましょう。

中編で学んだとおり、半音上げプラグインがやるべきことは「音符情報ファイルの NoteNum= の後ろの数字を 1 増やす」です。

とはいえ、いきなりはハードルが高いので、まずは音符情報ファイルの内容を表示するところから始めましょう。

半音上げプラグインの一歩手前のプラグインとして、「実行ボタンがクリックされたら音符情報ファイルの内容を表示する」プラグインを作ることにします。スクリプト表示プラグインに近いですね(スクリプト表示プラグインは内容の変更もできますが、今回作るのは単に表示するのみです)。

デザインタブの実行ボタンをダブルクリックし、デザインではない Form1.cs タブに ButtonGo_Click を作成してください。

ButtonGo_Click の中括弧 {} の間に以下の内容を貼り付けてください。

try
{
	Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
	String contents = File.ReadAllText(Environment.GetCommandLineArgs()[1], Encoding.GetEncoding("shift_jis"));
	MessageBox.Show(contents);
}
catch (Exception ex)
{
	MessageBox.Show("エラー:" + ex.Message);
}

上記プログラムコードを貼り付けた時、自動的にプログラムコードの一番上に

using System.Text;

が挿入されるはずですが、もし自動的に挿入されなかった場合は、こちらも併せて貼り付けてください。

内容表示の実行

再度ビルドしてから UTAU からプラグインとして起動してください。適当な音符を選択してからプラグインを起動してください。実行ボタンをクリックすると、音符情報ファイルの内容が表示されます。

OK ボタンで内容表示が消えるので、半音上げウィンドウの右上の×ボタンでプラグインを終了してください。

ちなみに、たくさんの音符を選択してプラグインを起動すると、内容表示が画面からはみ出て OK ボタンをマウスでクリックできなくなりますが、エンターキーを押せば大丈夫です。

内容表示の解説

さきほどのプログラムコードの動作を説明します。

try はいったんスルーして、次の Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); ですが、これは Shift-JIS 文字コードを使えるようにするための準備処理です。音符情報ファイルは文字コードが Shift-JIS なので、この処理が必要です。

次の行はイコール = の左右で分かれているのですが、先に右側から。

File.ReadAllText() はファイルの内容をすべて読み込む処理です。どのファイルを読むのかが Environment.GetCommandLineArgs()[1] で、これが音符情報ファイルのパスを表しています。Encoding.GetEncoding("shift_jis") で文字コード Shift-JIS での読み込みを指定しています。

さて、File.ReadAllText() でファイルの内容を読み込みますが、そのままだと単に読み込んだだけで、内容が宙に浮いてしまいます。内容を記憶しておくための処理がイコールの左側、String contents = です。

contents は「変数」(へんすう)と呼ばれるもので、内容を記憶しておくための箱だと思ってください。変数の名前が contents なのですが、名前はわりと何でも良いです。今回はファイルの内容という意味で英単語の contents にしましたが、ローマ字で naiyou にして String naiyou = でも構いません。適当に abc という名前にしてもプログラムとしては動作しますが、適当な名前にするとプログラムが何を処理しているのかが分かりづらくなってしまうため、きちんとした名前にすることをお薦めします。

変数は、どんな種類の内容を記憶するかを指定できます(これを「型」といいます)。今回は String を指定していますが、これは文字列を記憶できます。ファイルの内容は文字列なので String を指定するということです。ここでは使いませんが、他に例えば Int32 という種類があり、これは数字を記憶できます。

String contents = File.ReadAllText((中略)) とすることで、File.ReadAllText() で読み込んだファイルの内容を、文字列を記憶する contents 変数に記憶します。

イコールに違和感があるかもしれません。数学ではイコールは「等しい」という意味ですが、プログラムコードではイコールは等しいという意味ではありません。イコールは、「右側の内容を、左側の変数に記憶する」という意味です。これを「代入する」といいます。

次は MessageBox.Show(contents); ですが、MessageBox.Show() は前編でも使いました。メッセージを表示するという処理です。

前編では MessageBox.Show("いいね"); となっていて、"いいね" という文字列を表示しましたが、今回は変数 contents なので、変数 contents が記憶している文字列を表示します。つまり、音符情報ファイルの内容です。

ここまでの流れを整理すると、

  • File.ReadAllText() で音符情報ファイルの内容を読み込む
  • 読み込んだ内容を変数 contents に代入する
  • MessageBox.Show()contents に記憶した内容を表示する

となります。

さてここで、スルーしていた try についてです。

try は catch とセットで使用し、try の中括弧 {} の中でエラーが起きた場合は処理を中断し、catch にジャンプするという制御を行います。

何かエラーが起きたら、MessageBox.Show("エラー:" + ex.Message); が実行されるということです。

catch (Exception ex) の中の Exception exException 型の変数 ex です。Exception 型の変数はエラーの内容を記憶できます。エラーにまつわる内容をいろいろ記憶していますが、その中で Message はエラーメッセージです。つまり、何かエラーが起きたらエラーメッセージが表示されるということです。

試しに、UTAU からプラグインとして起動するのではなく、[デバッグ → デバッグの開始]メニューで Visual Studio から実行してみてください。プラグインの実行ボタンをクリックするとエラーメッセージが表示されます。

なぜエラーになるかというと、本来、File.ReadAllText() で音符情報ファイルを読み込みますが、UTAU から起動していないために音符情報ファイルが指定されていないためです。

後編 (A) まとめ

後編 (A) では半音上げプラグインのデザインを作成しました。また、動作の中身としては、半音上げプラグインの一歩手前、音符情報ファイルの内容表示を行いました。

次回、ついに半音上げプラグインの完成です。

次回

Discussion