本記事は「ツクールアドベントカレンダー Advent Calendar 2022」12月3日分の投稿記事です。
変数とは
RPGツクールシリーズには「変数」という概念があります。
プログラミングを嗜む人にとってはお馴染みの概念ですが、そうでない人にとっては最初につまずきやすい壁かもしれません。
ツクールの「変数」とは、数値を格納する箱のようなもののことです。
「スイッチ」がONかOFFかの二択の状態を表すのに対し、「変数」は任意の数を入れられます。数値なので四則演算や大小比較などもできます。
イベントコマンドの「変数の操作」では、指定した変数に任意の数値やゲーム内で定義されている値を、代入したり計算したりすることができます。
「条件分岐」では指定した変数の値が、ある値と等しいか、大きいか、小さいかなどで分岐させることが可能です。
その他、「数値入力の処理」では入力された数値を受け取る場所として変数を指定したり、「所持金の増減」や「HPの増減」などでは増減させる所持金やHPを変数で指定できたり、「場所移動」では移動先の座標を変数で指定することもできるなど、多数のイベントコマンドで変数は利用されます。
ツクールで凝った処理を作るには、この「変数」を使いこなすことが必須と言っても過言ではありません。
オペランド
変数で扱う数値は、「変数の操作」の「オペランド」で指定できます。
「オペランド」もプログラムを嗜む人でなければ馴染みがない言葉ですが、日本語に訳すと「被演算子」で、要は計算の対象となる値のことです。
オペランドは以下の5つから指定できます。
- 定数
- 固定の数値を直接指定します。
- 変数
- 指定した変数に格納されている数値を用います。
- 乱数
- 指定した範囲内の整数がランダムで選ばれます。
- ゲームデータ
- ゲーム内に登場する様々な値や番号が指定できます。
- スクリプト
- 直接スクリプト(プログラム)を記述して値を取得します。やや高度な機能です。
上記のうち「ゲームデータ」が、単純なようでいてかなり奥が深く、またこれを制覇することこそが変数の使いこなしの第一歩でもあるため、以下で詳しく説明していきます。
ゲームデータ
オペランドで「ゲームデータ」を選択すると、デフォルトで「マップID」と表示されます。
このデフォルトが「マップID」という点が、ゲームデータで何ができるのかを分かりにくくしているのではないかと思うのですが、右欄の「...」をクリックするとさらにウィンドウが開き、様々な項目を選べるようになっています。
階層の深いところにあるため、そもそもどのような要素が指定できるのか、ある程度ツクールに慣れている人でも完全に把握するのは難しかったりします。
それぞれ、どんなことができるのか、具体的な使用例を交えて解説します。
アイテム・武器・防具の所持数
指定したアイテム・武器・防具の所持数を取得します。
単純に所持しているかどうかは条件分岐でできますが、例えば「ポーションを10個持っているか」など指定数だけ所持しているかどうかは条件分岐一発ではできません。
このような場合、いったんポーションの所持数を変数に取得して、その変数が10以上かどうかで条件分岐することで可能になります。
◆変数の操作:アイテムの個数 = ポーションの数
◆条件分岐:アイテムの個数 >= 10
◆文章:ポーション10個、ありがとう!
◆アイテムの増減:ポーション - 10
:それ以外のとき
◆文章:ポーション10個、持ってきてちょうだい!
:分岐終了
注意点として、武器と防具については、装備中のものは所持数に含まれません。
装備中のものも含めて1個でも所持しているかどうかは、条件分岐の武器・防具で「装備品を含む」にチェックをすれば判別できますが、装備中のものも含めて複数個所持しているかどうかを調べるには、やや面倒ですが以下のようにする必要があります。
◆変数の操作:アイテムの個数 = ショートソードの数
◆条件分岐:リードがショートソードを装備している
◆変数の操作:アイテムの個数 += 1
:分岐終了
◆条件分岐:プリシアがショートソードを装備している
◆変数の操作:アイテムの個数 += 1
:分岐終了
……(アクターの分だけ繰り返し)
最初に(装備品を除いた)武器・防具の所持数を変数に取得し、続いて各アクターがその武器・防具を装備していれば変数に1加算します。こうすることで、装備中のものも含めた所持数を取得することが可能です。
条件分岐するのはその武器・防具を装備可能なアクターだけで十分ですが、対象アクターの数が多いとさすがにやってられないので、スクリプトなどを利用した方がいいと思います。対象アクターが数人程度であれば、やや面倒でも1人1人確認していく方法が、分かりやすいのではないかと思います。
アクター・敵キャラのパラメータ
指定したアクターや敵キャラの指定したパラメータを取得します。
パラメータは、アクターの場合、レベル・経験値・(現在の)HP・(現在の)MP・最大HP・最大MP・攻撃力・防御力・魔法力・魔法防御・敏捷性・運・TPが取得できます。敵キャラの場合、レベルと経験値は取得できません。
MVの頃はTPが取得できなかったのですが、MZになってTPも取得できるようになりました。
基本のパラメータは全て取得できるようになっていますが、回避率や会心率、狙われ率などの追加能力値や特殊能力値、耐性などは取得できません。
また、対象者が固定でしか選択できないため、実際に活用しようとすると力業にならざるを得なかったりと、やや使いづらい印象もあります。
よくある使い方としては、パーティーのレベルによる分岐などでしょうか。
例えば主人公のレベルが10以上かどうかで分岐したい場合は、いったん主人公のレベルを変数に取得して、その変数が10以上かどうかで条件分岐します。
◆変数の操作:主人公のレベル = リードのレベル
◆条件分岐:主人公のレベル < 10
◆文章:レベル10になってから来い!
:それ以外のとき
◆文章:ワシと戦う権利をやろう……。
:分岐終了
特定のアクターではなく、パーティーの平均レベルを取得したいという場合も多いかと思います。
イベントコマンドだけで平均レベルを算出するのはやや面倒ですが、人数がそれほど多くない場合は以下のようにして求められます。
◆変数の操作:平均レベル = 0
◆条件分岐:リードがパーティーにいる
◆変数の操作:平均レベル += リードのレベル
:分岐終了
◆条件分岐:プリシアがパーティーにいる
◆変数の操作:平均レベル += プリシアのレベル
:分岐終了
……(アクターの分だけ繰り返し)
◆変数の操作:平均レベル /= パーティ人数
まず最初に変数に0を代入します。
続いてそれぞれのアクターについて1人ずつ、パーティーにいるかどうかで条件分岐し、いる場合は変数にそのアクターのレベルを加算します。パーティー構成が固定メンバーの場合は、パーティーにいるかどうかの条件分岐は省略できます。
これをアクターの人数分繰り返して、最後にその変数を「その他」の「パーティ人数」で除算(割り算)します。
こうすることで、パーティーの平均レベルが算出できます。
変数は標準仕様では整数しか受け付けないため、割り算の際に割り切れない場合は、小数点以下が切り捨てられます。四捨五入だったり、小数点以下が保持されたりはしない点にご注意ください。
なお、アクターが何十人もいる場合は、さすがにスクリプトを使った方がいいと思います。
他にアクターのパラメータを使った例として、主人公のHPが半分以下になった場合を考えてみます。
この場合、2つの変数を使います。
片方は現在のHPを取得、もう片方は最大HPを取得します。
そして、半分なので最大HPを2で除算(割り算)します。
そして条件分岐で、現在のHPが最大HPを2で割った値以下かどうかを判別すれば、HPが半分以下かどうかで分岐ができます。
◆変数の操作:現在のHP = リードのHP
◆変数の操作:最大HP = リードの最大HP
◆変数の操作:最大HP /= 2
◆条件分岐:現在のHP <= 最大HP
◆文章:だいぶ消耗しているわね。
◆アニメーションの表示:プレイヤー, 回復/単体1(ウェイト)
◆全回復:リード
:それ以外のとき
◆文章:まだ元気そうね。
:分岐終了
慣れている人は、以下のように1つの変数だけでも、同じ処理ができます。
◆変数の操作:HP判別用変数 = リードの最大HP
◆変数の操作:HP判別用変数 /= 2
◆変数の操作:HP判別用変数 -= リードのHP
◆条件分岐:HP判別用変数 >= 0
◆文章:だいぶ消耗しているわね。
◆アニメーションの表示:プレイヤー, 回復/単体1(ウェイト)
◆全回復:リード
:それ以外のとき
◆文章:まだ元気そうね。
:分岐終了
何をしているかというと、最初に変数に最大HPを代入します。次に2で割って最大HPを半分にします。最後にそこから現在のHPを減算(引き算)します。
結果が0以上であれば、現在のHPが半分以下ということになります。結果が0未満(マイナス)であれば、現在のHPが半分より大きいことになります。
キャラクターの位置や向き
指定したキャラクターの位置や向きを取得します。
キャラクターは、プレイヤー、このイベント(現在起動中のイベント)、および現マップ中のイベントが指定でき、指定したキャラクターのマップ座標・向き・画面座標が取得できます。
特定の場所で使うと効果のあるアイテムを作る場合、プレイヤーの「マップX」と「マップY」、および「その他」にある「マップID」をそれぞれ変数に代入し、特定の値かどうかを判別することで実現できます。
◆変数の操作:現在のマップID = マップID
◆変数の操作:現在のX座標 = プレイヤーのマップX
◆変数の操作:現在のY座標 = プレイヤーのマップY
◆条件分岐:現在のマップID = 5(対象のマップID)
◆条件分岐:現在のX座標 = 20(対象のX)
◆条件分岐:現在のY座標 = 10(対象のY)
~アイテムの効果~
イベント処理の中断
:分岐終了
:分岐終了
:分岐終了
◆文章:しかし何も起こらなかった。
会話イベント中、「文章の表示」の直前に「移動ルートの設定」で「完了までウェイト」のチェックを外してキャラクターを移動させると、話をしながらキャラを動かすことができます。
この時、次の台詞はキャラの移動が終わってからにしたい場合、キャラが移動し終わったかどうかの判別は、ループを使って次のようにします。
◆移動ルートの設定:対象キャラ
: :◇下に移動
: :◇下に移動
: :◇下に移動
◆文章:ようこそ。いらっしゃいませ。
◆ループ
◆変数の操作:Y座標 = 対象キャラのマップY
◆条件分岐:Y座標 = 20(着地点)
◆ループの中断
:分岐終了
◆ウェイト:1フレーム
:以上繰り返し
◆文章:私がこの屋敷の主です。
その他、ミニゲーム等でオブジェクトの位置を把握したり、任意の地点からキャラクターを移動させたりする場合に、座標の取得は頻繁に利用されます。
パーティーのN番目のメンバーのアクターID
パーティー内の指定したメンバーのアクターIDを取得します。
指定した順番のメンバーがいない場合は0となります。
メンバーの入れ替えや並び替えができる作品では重要な役割を果たします。
ただシステム上、パーティーには何人でもメンバーを追加できるのですが、変数の操作で指定できるのは8番目のメンバーまでです。なんでだよ!
コアスクリプト的にも別に8人まででなければならない理由もなく、純粋に選択リスト上の仕様のように思えます。リストボックスじゃなくて、数値入力にしてくれれば、そんな制限なくていいはずなのに。
もっとも、パーティーメンバーが多い場合は、イベントコマンドでやるよりもスクリプトを使った方がはるかに効率的なので、8人までしか指定できなくても、それほど影響はないかもしれません。
イベントコマンドで「HPの増減」や「ステートの変更」「スキルの増減」など、アクター関連のコマンドの中には、対象アクターを変数で指定できるコマンドもあります。
先頭のメンバーだけ何らか影響を与えたいような場合、まず変数に1番目のメンバーのアクターIDを取得し、次に対象のアクターをその変数で指定します。
ただ、対象のアクターに変数が使えるのは「スキルの増減」までで、装備・名前・職業・二つ名・プロフィールの変更は、対象のアクターを変数で指定することができません。
装備の変更は装備の可不可もあるので分からないでもないですが、「装備の変更」(装備を外す)と「職業の変更」で変数が使えれば、ドラクエ3みたいな転職システムを作る場合に役立つのに、と思います。
また、アクターのパラメータを変数に取得する場合も、対象のアクターを変数で指定できれば、イベントコマンドでできる範囲が広がるのですが、固定でしか指定できないのが残念でなりません。
その他よく使う使い方としては、パーティーの先頭のメンバーに応じて台詞を変えるような場合が考えられます。
この場合、メンバー#1のアクターIDを変数に取得して、そのアクターIDによって分岐すればOKです。
◆変数の操作:アクターID = パーティメンバー1番のアクターID
◆条件分岐:アクターID = 1
◆文章:やあ、リード君。今日はいい天気だね!
:分岐終了
◆条件分岐:アクターID = 2
◆文章:やあ、プリシアちゃん。今日もかわいいね!
:分岐終了
……(アクターの分だけ繰り返し)
アクター名だけであれば、制御文字を使って \N[\V[x]]
のように記述もできます。xにアクターIDを取得した変数の番号を指定します。
選択肢でパーティーのメンバーを選ばせたい時などに役立ちます。
◆変数の操作:#0001 = パーティメンバー1番のアクターID
◆変数の操作:#0002 = パーティメンバー2番のアクターID
◆変数の操作:#0003 = パーティメンバー3番のアクターID
◆変数の操作:#0004 = パーティメンバー4番のアクターID
◆選択肢の表示:\N[\V[1]], \N[\V[2]], \N[\V[3]], \N[\V[4]]
:\N[\V[1]]のとき
◆変数の操作:アクターID = #0001
:\N[\V[2]]のとき
◆変数の操作:アクターID = #0002
……(アクターの分だけ繰り返し)
:分岐終了
厳密にやる場合はパーティーの人数などに応じてさらに分岐させる必要がありますが、選択肢の中で変数に選んだアクターIDを取得して、そのアクターIDのアクターに対する操作を行うことができます。
直前
「直前」はRPGツクールMZから追加された新機能で、MV以前にはありません。
- 直前に使用したスキルのID
- 直前に使用したアイテムのID
- 直前に行動したアクターのID
- 直前に行動した敵キャラのインデックス
- 直前に対象となったアクターのID
- 直前に対象となった敵キャラのインデックス
の6つから選べます。
いずれもアイテムやスキルから呼び出されるコモンイベントで活用するのが中心的な使い方になるでしょう。
「直前」と言っていますが、アイテムやスキルから呼び出したコモンイベント内では、そのアイテムやスキル、使用者や対象者が取得できるので、ご安心ください。
いくつか代表的な使い方としては、副作用のあるスキルが挙げられます。
例えば敵に大ダメージを与える代わりに、自分がスタンしてしまうスキルの場合、スキルの使用効果にコモンイベントを設定し、そのコモンイベントでは、変数に「直前に行動したアクターのID」(=使用者のアクターID)を取得し、「ステートの変更」で対象アクターにその変数を指定し、スタンを付加すればOKです。
◆変数の操作:アクターID = 直前に行動したアクターのID
◆ステートの変更:{アクターID}, + スタン
ただ、アクターの場合は「ステートの変更」で対象者を変数で指定できるので楽ですが、敵キャラにも同じことをさせたい場合、「敵キャラのステート変更」では変数指定できないので、敵キャラのインデックスを1~8まで判定してやる必要があり、かなり面倒です。
◆変数の操作:敵キャラ = 直前に行動した敵キャラのインデックス
◆条件分岐:敵キャラ = 1
◆敵キャラのステート変更:#1, + スタン
:分岐終了
◆条件分岐:敵キャラ = 2
◆敵キャラのステート変更:#2, + スタン
:分岐終了
……(8まで繰り返し)
その他、能力値アップ系のアイテムは、普通に作ると固定値でアップさせることしかできませんが、上昇量をランダムにしたい場合、「直前に対象となったアクターのID」と「直前に使用したアイテムのID」を用いて、以下のようにすることができます。
◆変数の操作:アクターID = 直前に対象となったアクターのID
◆変数の操作:アイテムID = 直前に使用したアイテムのID
◆変数の操作:上昇量 = 乱数 1..3
◆条件分岐:アイテムID = 31(最大HPアップアイテム)
◆能力値の増減:{アクターID}, 最大HP + {上昇量}
:分岐終了
◆条件分岐:アイテムID = 32(最大MPアップアイテム)
◆能力値の増減:{アクターID}, 最大MP + {上昇量}
:分岐終了
……(該当のアイテム分だけ繰り返し)
その他
最後に「その他」の項目で、様々な値を取得することができます。
取得できる値は読んで字のごとくですが、中には意外な応用ができるものもあり、なかなか奥が深くなっています。
「パーティ人数」は、現在のパーティーメンバーの人数を取得する項目です。
所定の人数が揃っていないと先へ進めないようにしたり、1人でないと入れないダンジョンを作ったりする時に役立ちます。
それ以外にも前述の通り、パーティーの平均レベルを算出する時や、パーティーメンバーの選択肢を作る時などに使えます。
「所持金」は、現在所持しているお金を取得できます。
例えば、全滅時に所持金を半分にしたい場合、以下のようにします。
◆変数の操作:減額分 = 所持金
◆変数の操作:減額分 /= 2
◆所持金の増減:- {減額分}
その他の使い方としては、ショップで買い物をする前と後とで所持金を比較することで、購入したか否かを判別することができます。
◆変数の操作:事前所持金 = 所持金
◆ショップの処理:……
◆変数の操作:事後所持金 = 所持金
◆条件分岐:事前所持金 ≠ 事後所持金
◆文章:毎度ありがとう!
:それ以外のとき
◆文章:冷やかしなら余所へ行ってくれ!
:分岐終了
ただし実際には、同時に売却を行って前後の所持金が同じになったケースも考えられるため、厳密な判別ではありません。購入のみで売却ができないショップであれば、所持金の比較で十分でしょう。
「歩数」は、単に歩いた歩数を取得するだけでなく、前後で比較することで、1歩移動したかどうかの判別に利用できます。
例えば並列処理するコモンイベントで歩数を比較すれば、1歩歩いた時の処理を行うことができます。
◆変数の操作:現在の歩数 = 歩数
◆条件分岐:現在の歩数 > 前回の歩数
~1歩歩いた時の処理~
:分岐終了
◆変数の操作:前回の歩数 = 現在の歩数
「プレイ時間」は、ゲームスタートから現在までのプレイ秒数を取得できます。一定時間で復活する敵キャラや宝箱などを実装する際に役立ちます。
「セーブ回数」は、文字通りセーブを行った回数を取得するものですが、コモンイベントの並列処理で上述の歩数と同様にセーブ回数を比較することで、セーブを行った直後に何らかの処理を行うことができます。
また、セーブポイントでセーブする仕組みの場合、前後でセーブ回数を比較することで、実際にセーブを行ったかキャンセルしたかを判別することができます。
「戦闘回数」なども、並列処理で回数を比較することで、ランダムエンカウントの戦闘終了後に処理を挟むことができます。
まとめ
以上、「変数の操作」の「ゲームデータ」の中身を解説してきました。
階層が深いところにあったり、ツクールのバージョンによって機能が追加されていたりするため、ベテランツクラーでもなかなか使いこなすのは難しいです。
ぱっと見では何に使えるのかピンと来ない項目もありますが、意外な使い方ができる項目もあったりして、使いこなせればいろいろな複雑な処理も、プラグインを使わずとも実装できる場合があります。
皆さんもぜひ、変数を使いこなしてみてください。
今回は変数のうち、「ゲームデータ」の活用法を解説しましたが、変数にはこれ以外にまだまだたくさんの使い方があります。そちらも近いうちに解説記事を公開する予定ですので、どうぞお楽しみに。