見出し画像

RPGツクールプラグイン制作過程紹介 第6回

前回からやや時間が空いてしまいましたが、第6回に入っていきたいと思います!

プラグインコマンド

前回の最後にてイベントコマンドのスクリプトで自作関数を呼び出しましたが、これを毎回記述するのは大変である、というお話をしました。

スクリーンショット 2021-04-04 21.12.56

そこで今回はこの処理をプラグインコマンド化していきます。
プラグインコマンドとは、そのプラグインにて利用できる専用のイベントコマンドのようなものです。公式・個人を問わず多くのプラグインに用意されているので、使ったことがおありの方もいらっしゃるでしょう。プラグインコマンドは自由に作ることができますが、それはつまりイベントコマンドを自作できるということなのです。これは昔からのツクラーにとっては夢のような機能と言えるでしょう!

それでは早速見ていきましょう。
プラグインコマンドを設定するには、大まかに以下の三つの手順が必要です。

1. アノテーションにプラグインコマンド本体を定義する
2. アノテーションにプラグインコマンドの引数を定義する(引数不要の場合省略可)
3. PluginManagerにコマンドを登録する

順番に見ていきましょう。

アノテーション記述

プラグイン上部にあるコメント部分をツクールでは「アノテーション(注記)」と呼んでいます。JavaScriptにおけるコメントは通常、プログラムの動作には何の影響も及ぼしません。そのためコードのある部分にメモを入れることで備忘録としたり、コードの一部をコメント化することで一時的に動作させないようにしたり(コメントアウト)することができるわけですが、アノテーションは少し特殊で、プログラムにも影響を与えるコメントです。といっても直接ゲーム中の動作に影響を与えるというよりは、ツクールのエディタ上での挙動に対する影響です。

これを利用することでMZ用プラグインであることを明示したりプラグインのヘルプを記述したり、あるいはそのヘルプを多言語対応したりとさまざまなことができるのですが、やはりアノテーションのもっとも重要な用途はプラグインパラメータおよびプラグインコマンドでしょう。

それではアノテーションの書き方を見ていきましょう…といっても実は、そのためのフォーマットは以前に作成済みなのです。

スクリーンショット 2021-04-25 17.59.55

JavaScriptには大きく分けて2種類のコメント記述方法があります。
一つは「//」を使用する一行コメントです。

// これはテストコードですよ〜
const test = "Hello, World!";

一行コメントはその名の通りその行しかコメント化しません。それに対して、「/*」と「*/」で囲む複数行コメントは囲んでいる部分全てをコメント化します。

/*
ここはコメントなので何書いたっていいんです!
そう、コードっぽい文だろうと日記だろうと何でもいいんです!
const fugafuga = hogehoge;
*/
const test = "Hello, World!";

ツクールのアノテーションは複数行コメントを利用するものですが、全ての複数行コメントがアノテーションとして扱われるわけではありません。「/*:」で始まるものだけがアノテーションとしてみなされます。

/*:
 * @target MZ
 * ....
 */

公式プラグイン講座より抜粋)

毎回この枠を手打ちするのはやや面倒なので、ロンチプラグインなどを加工してテンプレートにすると便利ですね。
そう、第1回でこの枠を残しておいたのはこのためだったのです。

それでは早速プラグインコマンドを作っていきましょう。プラグインコマンドは以下の書式でアノテーション枠内に記述することで定義可能です。

* @command COMMAND
* @text コマンド名称
* @desc コマンド説明
*
* @arg arg1
* @text 引数の名称
* @desc 引数の説明

公式プラグイン講座より抜粋)

この書式は2つの部分に分かれています。上はプラグインコマンド本体の定義、下は引数の定義です。

本体の@commandにはそのコマンドの識別子を入力します。関数名のようなものなので、命名規則も関数名や変数名と同様の制限があります。
@textはエディタ上に表示されるコマンドの名前です。通常の日本語による記述ができます。
@descもエディタ上に表示される説明文であり、平文記述が可能です。

引数はプラグインコマンドのパラメータの定義です。
パラメータ不要の場合、省略することができます。
@argは引数の識別子です。
@text@descは本体と同様です。

では実際に書いてみます。今回は前回作った関数のtoggleSwitchesByFacingSkillTargetsをコマンド化するので、名前もこれと同名にすることにします。
まずは日本語で記述するので、/*:jaで囲まれている方に記述します。

/*:ja
* @target MZ
* @plugindesc 
* @author 
*
* @help 
*
* @command toggleSwitchesByFacingSkillTargets
* @text 直前イベントスイッチオン
* @desc プレイヤーの目の前のイベントのメタタグに設定されているスイッチをオンにします。
*
* 
*/

たったこれだけでOKです。toggleSwitchesByFacingSkillTargetsには引数がありませんので、@arg以下は不要です。

ところでアノテーションの説明は多言語対応が可能なのですが、今回は日本語なので/*:の後にjaを付けたセクション内に記述しました。言語を特に指定しないセクションの場合(/*:の後に何も書いていないセクション)、英語環境用になります。
なおこれはツクール本体の言語設定に応じてエディタ上に表示される文言が変わるというものであり、作られたゲームには影響しません。

日本語ユーザーにのみ公開するプラグインの場合は上記だけで問題ないのですが、もしグローバルに公開したいという場合は英語表記も用意しておいた方が親切です。思いやりの気持ちを大事にしていきましょう!
今回は以下のようにしました。

スクリーンショット 2021-04-25 22.29.08

@command部分は共通です。このように、アノテーションは説明文以外は同一のものを言語の数だけ用意します。

ここまでできたら保存して、何でもいいのでツクールのイベントを開いてプラグインコマンドを確認してみましょう。プラグイン名からFieldAction.jsを選択します。

スクリーンショット 2021-04-25 18.54.46

するとコマンド名に先ほどの直前イベントスイッチオンが現れるはずです。

スクリーンショット 2021-04-25 18.56.03

現れていれば、正常に設定できています。

ただし現時点ではまだこのコマンドの中身は設定していませんので、何も起きません。
続いて中身を作っていきましょう。

PluginManagerへのコマンドの登録

プラグインコマンドの実際の処理は、PluginManagerと呼ばれるプラグイン管理用マネージャから呼び出されます。

これも書式がほぼ決まっていて、以下のようになります。

PluginManager.registerCommand("プラグイン名", "コマンド名", args => {
    // 処理
});

プラグイン名はその名の通りこのプラグイン自体の名前です。ですのでコマンドをいくつ登録するとしても、この部分は"FieldAction"でいいのです(拡張子不要)。
コマンドごとに同じ文字列を記述するのはミスの元になるということもあり、プラグイン名は原則として定数に代入した方が望ましいです。

コマンド名は対応するプラグインコマンド名を入力します。今回の場合上記で設定したtoggleSwitchesByFacingSkillTargetsをそのまま使いますが、文字列として代入するので""で囲みます。

すると以下のようになるはずです。

スクリーンショット 2021-04-25 19.34.04

続いて具体的な処理を中に記述します。
中身は前回イベントのスクリプトに書いたものと全く同じで問題ありません。
以下のようになります。

PluginManager.registerCommand(PLUGIN_NAME, "toggleSwitchesByFacingSkillTargets", args => {
    $gamePlayer.toggleSwitchesByFacingSkillTargets();
});

$gamePlayer、つまりプレイヤーのtoggleSwitchesByFacingSkillTargets関数を呼び出す、という処理です。実にシンプルですね。
この関数には引数がありませんのでこれだけで完結しているのですが、引数をプラグインコマンドに設定する処理が必要な場合もう少し複雑になります。今後の回でご紹介したいと思います。

できたら保存して、前回のコモンイベントのスクリプト部分をプラグインコマンドに置き換えてみます。

スクリーンショット 2021-04-25 21.33.23

それでは実行してみましょう!

スクリーンショット 2021-04-25 21.36.56

今回はあくまでもスクリプト部分をプラグインコマンドに置き換えただけですので、何も動作が変わらないことこそが正常な動作である、ということになります。
これでプラグインコマンドができました!

まとめ

今回はプラグインコマンドの作り方を見てきました。

イベントのスクリプト記述部分をプラグインコマンド化することにより、グッとエディタ上で設定しやすくなったと思います。
これはプラグイン利用者にはもちろん、プラグイン作者にとっても記述ミス防止などに役立つはずです。

これを応用すればさまざまな動作をイベントコマンド化できますので、どんどんイベントを改造することだってできてしまうのです。
書き方にはやや慣れが必要ですが、積極的に活用していきたいですね。

次回はフィールドアクションの種類の使い分けについてご紹介する予定です。
それではまた次回お会いしましょう!

参考資料

アノテーションに関して詳しく知りたい場合、まずは公式プラグイン講座をご覧ください。

RPGツクールMZ プラグイン講座

また、とんび@鳶嶋工房さんが上記にも掲載されていない非常に詳細な仕様を調査してまとめてくださっています。
とんび@鳶嶋工房さんに深謝いたします。

RPGMakerMZ / Reference / MV.PluginSettings.md

今回までの最終コード

//=============================================================================
// RPG Maker MZ - 
//=============================================================================

/*:
* @target MZ
* @plugindesc 
* @author 
*
* @help 
*
* @command toggleSwitchesByFacingSkillTargets
* @text Turn Switches on by Events Faced by Player
* @desc Turns on switches whose IDs correspond to <skillSwitchId: > note of events faced by the player.
*
* 
*/

/*:ja
* @target MZ
* @plugindesc 
* @author 
*
* @help 
*
* @command toggleSwitchesByFacingSkillTargets
* @text 直前イベントスイッチオン
* @desc プレイヤーの目の前のイベントのメタタグに設定されているスイッチをオンにします。
*
* 
*/

(() => {
   'use strict';


   const PLUGIN_NAME = "FieldAction";
   
   PluginManager.registerCommand(PLUGIN_NAME, "toggleSwitchesByFacingSkillTargets", args => {
       $gamePlayer.toggleSwitchesByFacingSkillTargets();
   });


   Game_Player.prototype.facingSkillTargets = function() {
       const direction = this.direction();
       const x1 = this.x;
       const y1 = this.y;
       const x2 = $gameMap.roundXWithDirection(x1, direction);
       const y2 = $gameMap.roundYWithDirection(y1, direction);
       const events = $gameMap.eventsXy(x2, y2);
       return events;
   };
   
   Game_Player.prototype.isFacingSkillTargets = function() {
       const events = this.facingSkillTargets();
       return events.length > 0;
   };
   
   Game_Player.prototype.toggleSwitchesByFacingSkillTargets = function() {
       const events = this.facingSkillTargets();
       for (const event of events) {
           const switchId = event.skillSwitchId();
           $gameSwitches.setValue(switchId, true);
       }
   };
   
   
   Game_Event.prototype.skillSwitchId = function() {
       return this.event().meta.skillSwitchId;
   };

})();

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