【解決】プラグインパラメータの演習がうまくいきません。

アバター
サブちゃんB
記事: 27
登録日時: 2018年3月06日(火) 01:09

【解決】プラグインパラメータの演習がうまくいきません。

投稿記事by サブちゃんB » 2022年11月26日(土) 01:22

プラグイン開発の理解を深めるべく、下記のページを元にRPGツクールMZ Version 1.5.0で演習を行っています。

プラグインの作り方入門その6:スイッチに応じてゲームオーバーの処理を変更(プラグインパラメーター) #RPGツクールMZ #RPGツクールMV
https://fungamemake.com/archives/12434

7 リファクタ(コード改善)と 競合対策(重複コードをフック)
まではうまくいったのですが、
8 プラグインパラメーターの追加
では、指定したスイッチのオン・オフに関わらず一定の動作しかしません。
※当該スイッチのオン・オフにかかわらず{}内が実行されてしまいました。

自分の書き方が悪かったのかと思いサンプルコードをコピペして実行しましたが、やはり結果は同じです。
8のサンプルコードだけのために新しいプロジェクトを作成しましたが、同じ結果です。

×24行目、
×if (!$gameSwitches.value(gameOverSwitchId)
×のgameOverSwitchIdを整数に置き換えて直接指定すれば正常に動作しました。
↑上記三行はサンプルコード等を参考に別途試作したコードの結果であり、新しいプロジェクトでサンプルコードを実行した際は直接整数で指定しても当該スイッチのオン・オフにかかわらず{}内が実行されてしまいました。

MV用に書かれたコードであることが原因ならばMZ用にカスタマイズする必要があるかと思って調べてみましたが、公式のプラグイン講座も含めて、参考にできそうなプラグインパラメータ(特にスイッチ)の実例を発見できず、頭を抱えております。

これをうまく動かすためにはどうすればいいか、またはこの辺の理解を深めるための教材がございましたらご教示頂けますと嬉しいです。
宜しくお願い致します。
最後に編集したユーザー サブちゃんB on 2022年12月08日(木) 18:12 [ 編集 1 回目 ]

名無し蛙
記事: 302
登録日時: 2015年11月23日(月) 02:46

Re: プラグインパラメータの演習がうまくいきません。

投稿記事by 名無し蛙 » 2022年11月26日(土) 03:27

パッと見る限り普通にサンプルコード自体のコーディングミスですね
7の最後のコードと8のコードをよく見較べてください
プラグインパラメータに関連した処理以外にも説明もなく変更された差異があります
それが動かない原因です
アバター
サブちゃんB
記事: 27
登録日時: 2018年3月06日(火) 01:09

Re: プラグインパラメータの演習がうまくいきません。

投稿記事by サブちゃんB » 2022年11月26日(土) 15:40

名無し蛙様、ご教示頂きましてありがとうございました!
やはりサンプルコード自体に問題があったのですね。

https://docs.google.com/document/d/1pn8 ... sp=sharing

7と8を比較して、25行目の.call(this)が抜けていることに気がつきました。
サンプルコードへ.call(this)を追記したところ、
少なくとも整数による直接指定で正常に動作しました。

サンプルコードとは別に
Window_Base.prototype.drawCurrencyValue
を使って条件分岐をさせる方法でgameOverSwitchValの変化で処理変わるかどうかをテストした際に
直接整数で指定すると正常に動作したことの説明が付くところまで進みました。
大変助かりました。

あとは……。
やはり、プラグインパラメータ部分にも問題があるということですね。
アバター
サブちゃんB
記事: 27
登録日時: 2018年3月06日(火) 01:09

Re: プラグインパラメータの演習がうまくいきません。

投稿記事by サブちゃんB » 2022年11月26日(土) 15:54

たびたび失礼します、ほぼ自己解決しました!
9 完成品の47行目に.call(this)を追記して実行したところ、正常に動作しました!

今のところ分かっている差異が42行目
const gameOverSwitchId = Number(parameters['Game Over Switch Id'] || 0);
の || 0ですので、まずはこの辺について調べてみたいと思います。
ありがとうございました。

40行目
const pluginName = document.currentScript.src.split("/").pop().replace(/\.js$/, "");
にも気がつきました。
定数pluginNameとプラグインのファイル名は合わせないといけないということですね。
chro
記事: 86
登録日時: 2021年2月14日(日) 11:26

Re: プラグインパラメータの演習がうまくいきません。

投稿記事by chro » 2022年11月27日(日) 01:22

liuhong さんが書きました:9 完成品の47行目に.call(this)を追記して実行したところ、正常に動作しました!

今のところ分かっている差異が42行目
const gameOverSwitchId = Number(parameters['Game Over Switch Id'] || 0);
の || 0ですので、まずはこの辺について調べてみたいと思います。

.call(this)は、予め代入しておいた関数(メソッド)をthisを指定して実行します。
()が関数の実行ですので、これがないと、ただ単に変数を参照しているに過ぎません。

コード: 全て選択

var num;
//代入されていない場合(falsyの場合、||の右側を返す)
Number(num); //NaN (Not-A-Number)
Number(num || 0); //0

//文字列などの数値に変換出来ないものが入っていた場合
num = 'a';
Number(num || 0); // NaN;

//数値以外が入っていた場合の対策。
//一度数値に変換した後に、NaNだったら0にする
//数値の場合、この形の方がいい。
Number(num) || 0 // 0;

//文字列に変換する場合、数値と違って文字列になってしまう。
var str;
String(str); //'undefined'
String(str + 1); //'NaN'
//文字列の場合はこの形が必須
String(str || ''); // ''



論理和 (||)
https://developer.mozilla.org/ja/docs/W ... Logical_OR

論理積 (&&)
https://developer.mozilla.org/ja/docs/W ... ogical_AND

1 && 2 //2
1 || 2 //1
0 && 2 //0
0 || 2 //2

スイッチ1がオンかつスイッチ2がオンの場合などの判定に使用します。
アバター
サブちゃんB
記事: 27
登録日時: 2018年3月06日(火) 01:09

Re: プラグインパラメータの演習がうまくいきません。

投稿記事by サブちゃんB » 2022年12月02日(金) 23:31

chro様、ご教示ありがとうございます!

>.call(this)

文中で「フック」と説明されていたこれを漠然としか理解していませんでしたが、ご教示頂いたことでより調べやすくなりました。
問題の切り分けもうまく出来ていなかったので、「ない場合はただの参照、あると実行」ということを明確にして頂けて助かりました。

>||

論理和についてもご教示頂き感謝致します。
一応論理演算子であろうことは分かったのですが、なぜ必要なのか、必要な場合はどういうときなのかについてうまく理解出来ていなかったので、こちらも大変助かりました。
論理和については、複数のスイッチが関係するときに必要となるということですね。

今日当該ページを閲覧すると、8のサンプルコードが修正されていて、ちゃんと動くようになっていました。
サンプルのプラグインパラメータスイッチについては、pluginNameはファイル名と一致している必要がなく、||0がなくても正常に動作しました。
ここでご教示頂いたことを応用してプラグインパラメータ変数を使ったテストコードを作りましたが、pluginNameを一致させたらうまく動きました。(一致させないとプラグインパラメータ変数が取得できませんでした)
pluginNameとファイル名との一致が必須かどうかについてはまだよく分かっていませんが、一致させた方が安全そうであるということは分かりました。

追記:||0について、本文中に解説がありました。後で追記された可能性もありますが、恐らくサンプルコードが動かないことに夢中で見落としていたのだろうと思います。
名無し蛙
記事: 302
登録日時: 2015年11月23日(月) 02:46

Re: プラグインパラメータの演習がうまくいきません。

投稿記事by 名無し蛙 » 2022年12月03日(土) 17:18

liuhong さんが書きました:pluginNameとファイル名との一致が必須かどうかについてはまだよく分かっていませんが、一致させた方が安全そうであるということは分かりました。
こう言った疑問が出るという事は恐らくご存知無いと思うので一応補足しておきます。
お察しの通り、プラグインパラメータを利用する場合はpluginNameとファイル名が一致する必要があります。
例外はありません。
しかしそれを意識してこなかった、という事はファイル名を変更して保存されていたのでしょう。
何故それでもプラグインが利用出来たかというと
一般的に流通しているプラグインはファイル名を自動取得する事がテンプレ化しているからです。

liuhong さんが書きました:40行目
const pluginName = document.currentScript.src.split("/").pop().replace(/\.js$/, "");
にも気がつきました。
定数pluginNameとプラグインのファイル名は合わせないといけないということですね。
具体的に言えばこの部分です。
厳密に説明すると非常に長くなるのでかいつまんで説明しますが、仮にファイル名をTestPlugin.jsとすると
document.currentScript.srcとは呼び出したプラグインのURIを取得するコードで
"chrome-extension://njgcanhfjdabfmnlmpmdedalocpafnhl/js/plugins/TestPlugin.js"という文字列を取得出来ます。
.split("/")とは文字列を指定されたデリミタ文字で分割、配列化するメソッドで
["chrome-extension:","","njgcanhfjdabfmnlmpmdedalocpafnhl","js","plugins","TestPlugin.js"]という配列に変換されます。
.pop()とは配列の末尾の要素を切り取って取得するメソッドで
"TestPlugin.js"に変換されます。
.replace(/\.js$/, "")は文字列末尾の".js"という部分を""に変換するコードで
"TestPlugin"に変換されます。
つまり最終的にpluginName = "TestPlugin"と等しい結果になる、という事です。

この辺の正確な挙動は理解する必要は無いです。
個人的には最低限、説明されて納得出来る程度の知識は押さえおいた方が良いと思いますけどね。
多くのプラグイン作者も先人が作ったプラグイン名を自動取得するテンプレを
「そういうもの」と踏襲しているだけだと思います。
document.currentScript.srcからどのようにプラグイン名を抽出するか、については
色々と議論されて改良されてきたんですけど自分は今はこちらのブログの方と同じ方法を採用していますね。
chro
記事: 86
登録日時: 2021年2月14日(日) 11:26

Re: プラグインパラメータの演習がうまくいきません。

投稿記事by chro » 2022年12月03日(土) 18:56

スイッチ1がオンの場合、変数11の値。もし変数11が0の場合は、変数12の値。
スイッチ1がオフの場合、変数12の値。

ツクール上はこうなります。条件が複雑になってきます。
rr1.png
rr1.png (46.58 KiB) 閲覧数: 788 回


組み替えると、スイッチ1がオンかつ変数11が0以外は、変数11の値。
スイッチがオフの場合と、変数11が0の場合は、変数12の値。
rr2.png
rr2.png (39.79 KiB) 閲覧数: 788 回



スイッチ1がオンなら、変数11の値を取得し、0なら変数12。
スイッチがオフなら、変数12の値。この時、変数11は評価されない。
論理積の中の短絡評価というものです。
ツクールでいう、条件分岐の中は飛ばされて実行されないようなイメージです。

コード: 全て選択

var number = $gameSwitches.value(1) && $gameVariables.value(11) || $gameVariables.value(12)


知っておくといいのは、ツクール上でのイベントの組み方がかなり違ってくると思います。
アバター
サブちゃんB
記事: 27
登録日時: 2018年3月06日(火) 01:09

Re: プラグインパラメータの演習がうまくいきません。

投稿記事by サブちゃんB » 2022年12月08日(木) 15:27

chro様、名無し蛙様、大変ご丁寧なご解説、誠にありがとうございました。

URIの取得と抽出につきましては、他のことにも応用できそうな大変貴重な知見です。

論理和と論理積については真理値表の関連から存じてはおりましたが、「短絡評価」という名称で効率的な組み方に応用されていることまでは存じ上げませんでした。

大変勉強になりました。
改めましてご教示頂き、感謝申し上げます。

“MZ:質問” へ戻る