● 覚書:MODを作ってみる 三人称視点MODを入れていると、色々調整しても自分の環境では、会話モードでプレーヤーの体がNPCの顔に被ってしまいます。そこで会話時にプレーヤーを半透明にするMODを作りたいと思います。ついでに過程を覚書します。 Construction Set(以下CS)が無ければ、始まらないのでCSを用意します。CSについては、Wikiに詳しい情報があります。 http://wiki.oblivion.z49.org/?MOD%2FTool%2FConstructionSet 最新のOBSEを導入して、obse_loader.exe のショートカットを作り、リンク先を「(obseのディレクトリ)\obse_loader.exe -editor」とすれば、OBSE環境のCSが使えます。OBSE対応のスクリプトを作ったり改変する時は、これが無いと出来ません。 スクリプトのファンクションなどを知るためには、Oblivion Wiki JP (避難所)の解説のURLから落とせる、「CS Wiki日本語化ヘルプファイル」が妥当です。 慣れてきたら、日本語ヘルプの元となった、CS Wiki(英語)のほうで更に調べてみるといいでしょう。 MODと言っても色々ありますが、ここではスクリプトを使用したMODを作りたいと思います。ヘルプにはチュートリアルなどもあるので、一読しておくと解り易いかも知れません。 古くはN88−BASICとか、MSX−BASICなんかをいじった事がある人(ベーマガとか読んだことある人)は、スクリプトを理解しやすいと思います。 ここでは最初からやりますが、実際はいきなり最初から一から作れないのが普通だと思うので、最初は既存のMODを改変してみるところから入るのがいいんじゃないでしょうか。適当にいじっているだけで色々覚えられます。 まず、どのタイミングでMODを動作させるか、決めておきます。 CSでは、スクリプトに「begin 〜(モード)」を書く事で、普通に移動している時か、メニューの時か、アイテムを装備した時か、などタイミングを決める事ができます。 会話(メニューモードの一部)の状態時に、プレーヤーを透明にしたいので、とりあえず「begin MenuMode」で動作するスクリプトを書こうと思います。同じスクリプト上で、別々のモードの処理を同時に走らせる事もできます。 メニューモードのどの状態で走らせるか決める事ができるので、会話モードの時のみにしようと思います。Negotiate(交渉)というモードがありました。このモードで走らせてみる事にします。 スクリプトを書くには、CS上のエディタでも可能ですが、ウィンドウズ付属のメモ帳よりも使いにくい(コピー&ペーストすらない)と思うので、専門のテキストエディタで編集してコピペするのがオススメです。 ここでは サクラエディタ を使います。このエディタは行番号が表示できるので、デバッグしやすく、全角スペースが見えるのでスクリプトを書くには使いやすいと思います。 まず手始めに、ScriptName を決めなくてはなりません。文頭に「aaa」を付けておきます。こうしておくと、CSでこのスクリプトを再編集したい時に、リストの先頭に来て探し易くなります。 今回は、aaaNegotiateViewScript と適当に付けておきました。CS上ではここで定義した名前でスクリプトが登録されます。 次に動作するモードを定義します。動作させたいメニューモードの種類、Negotiate(交渉)の番号は1025だったので、begin MenuMode 1025 とします。これでこれ以降の処理は、交渉モードでのみされるはずです。 begin は最後に必ず end を付ける必要があるので、付けておきます。 ヘルプのFunction タブから、プレーヤー(アクター)の透過度を決めるファンクションを探します。SetActerAlpha というファンクションがそのようです。アクターとは「役者」つまりキャラクター全般の事です。 日本語ヘルプに記載されているファンクションは、OBSEのファンクションを含んでいないようです。OBSEのファンクションに関しては、CS Wiki(英語) で解説されています。 ヘルプファイルで説明されている構文に従って、begin MenuMode 1025 以下に、Player.SetActorAlpha 0.4 と書き加えてみます。 Player. と付け加える事で、プレーヤーが対象になります。 数値(透過度)はとりあえず0.4としました。数値が低いほど透明度が増すようで、1.0で透明度無し、0.0で完全に透明になるようです。 これで、交渉の時にプレーヤーは半透明になるはずです。 しかし、このままだとずっと半透明のままなので、メニューから抜けたら元に戻すように処理しなければなりません。 別のモードの処理も続けて書いていきます。begin GameMode で、透過度を元に戻すようにします。このモードはゲームでプレーヤーが移動できるモードの時の処理です。 これで、交渉の時に半透明に。会話を止めて移動できるモードになると元に戻るように動くんじゃないかと思います。 このスクリプトはゲーム時に常に監視され、大体2〜3秒おきくらいに繰り返し実行されます。 このままでもちゃんと動きそうですが、移動中は必ず透過が解除されてしまうので、他のMODとの互換性を考えて、このスクリプト上で半透明になった後にのみ半透明を解除させるように、フラグを立てて処理をしたいと思います。 フラグを作るのに便利なのが、「変数(Variable)」です。変数は数字や文字を保存して、計算に使ったり、メッセージ表示に使ったりもできます。 フラグとして使うので、整数の0と1くらいが使えればいいので、ここでは short の変数を使用したいと思います。 スクリプトネームの下に、short frag という変数の使用を宣言します。宣言してからじゃないと使えません。「frag」 というは私が適当に付けた変数名で、別に何でも良いです。(フラグなら正確には「Flag」ですが、普通の変数名はスペルおかしくても関係ないので大丈夫です)とにかくこれで frag という変数をこのスクリプト上でのみ使用できます。 begin MenuMode 1025 (会話モード)でキャラクターを半透明にした後、set frag to 1 で frag 変数を1にしておきます。まずこうしておく事で、会話モードに入った時、フラグは1にセットされます。 次に、移動できるモードで、フラグに1セットされていた場合にのみ、プレーヤーの透過度を戻すように、Player.SetActorAlpha 1.0 を、if frag == 1 と endif で挟みます。 IF (もし) は処理の分岐に便利なステートメントです。詳しくはヘルプでも説明されています。これも最後に、ENDIF で終わらせる必要があります。 つまり、この間の処理は会話モードでフラグが1になっていないと実行されずスルーされます。 その後、set frag to 0 でフラグを0に戻してしておきます。 これで常にプレーヤーの透過度が元に戻される事はなくなり、他のMODとの互換性が増しました。 とりあえず、これで完成しました。編集エディタで作ったスクリプトを普通のテキストとして別に保存しておくと後で見直す時に楽です。 テキストエディタで完成させたスクリプトを、CSに張ってMODにしてみましょう。 「スクリプト編集」で、CSのエディタを開きます。
スクリプトタブから、新規作成を選択します。
スクリプトのタイプを指定しておきます。Object はアイテムやNPCに仕掛けるタイプ、Quest はクエストから実行するタイプ、Magic Effect は、魔法として実行するタイプです。 このタイプによって使える Begin や、ファンクションも若干違ってきます。 ここでは、ゲームが始まったら自動でスタートさせたいので、「Quest」にしておきます。
CSのスクリプトエディタにはコピーやペーストのボタンも無いので、編集エディタで全体コピーしたものを、「Ctrl+v」キーでペーストします。(OSヒープが十分でないと出来ない場合もあります。余計なアプリは閉じておきましょう) あとは保存ボタンを押します。実際には完全には保存されず、まずスクリプトのチェックがされます。 スクリプトに誤りがある場合は、エラーが出ます。表示される行番号を参考に、編集エディタでエラーを訂正します。エラーがある限り保存は一切出来ません。 上の画像の場合は、行番号8に、構文エラー(不正なBegin)と指示されています。 間違いを見つけて訂正し、再度保存ボタンを押してエラーが出なければ、スクリプトとして認められ、使うことができます。そのままエディタを閉じて下さい。エラーが出ている限り、そのスクリプトは一切保存されません。 次にこのスクリプトをクエストにして自動実行させるようにしましょう。クエストと言っても難しい事はありません。ただ、ゲームが始まったら自動的にスクリプトを読ませるだけですから。 CSのタブから「Quests...」を選択します。
クエストエディタで右クリックし、「新規作成」し、新しいクエストを作成します。
クエストのIDを適当につけます。別にゲーム中で表示される訳ではないので、他と被らなければ何でも良いと思います。文頭に「aaa」でも付けて置けば、並びが最初になるので良いかも知れません。
クエストデーターで、「Start Game Enabled」(ゲーム開始と同時にクエスト開始)のチェックがついている事を確認して、「Script」 から先ほど作ったスクリプトを指定しておきます。 指定できない場合は、スクリプトタイプが「Quest」になっているかもう一度確認する必要があります。クエストで使用できるスクリプトは、「Quest」タイプのみです。 Quest Name はゲーム中のクエスト名ですが、表示しないのでどうでもいいです。(一応名前付けましたけど、付けなくていいみたいです) Priorityは自分もよく解らないのですが、優先度の指定で日本語ヘルプにも説明があります。とりあえず自分は「その他のクエスト」として50としました。
さてこれで、自動スタートされるようになったので、MODはほぼ完成です。 クエストエディタをOKで閉じて、espとしてセーブをして下さい。 Wrye Bash を導入している人は、アクティブにするのを忘れずに。 さてゲームを起動して、テスト実行してみましょう。 ・・・・・・・。 あれ? ダメでした。半透明になりません。 何がいけなかったのでしょうか。 Negotiate(交渉)は、会話モードという意味では無かったのでしょうか、、、。 そういえば、話術ゲームがありましたね。ああ、あれが、Negotiate(交渉)か! と間違いに気づきました。 後から色々と試してみたのですが、どうやら会話シーンのモードは、1009 の Dialog だったようです。 スクリプトの begin MenuMode 1025 を begin MenuMode 1009 に修正してCSで再度保存。espをセーブしてゲームでもう一度確認してみます。 成功。画像では解りにくいですが、手前で被っているプレーヤーは半透明になっています。 透明度を調整して完全に透明にしてしまってもいいかも知れませんね。 意図した通り、会話から抜けたらちゃんと元に戻ります。 ただ、処理のタイミングが割りとスローペースなので、一呼吸置いてから半透明になるという感じです。 MODはほぼ完成していますが、ここでもう一つ処理を付け足しておきます。 前述した通り、スクリプトはユーザーが指定しない限り、通常4カウント(体感的には2、3秒)の間隔で、繰り返し実行されています。 これの間隔をもっと短くして、もっとキビキビと処理をさせるようにします。 fQuesetDelayTime という変数を定義する事で、スクリプトの処理の時間間隔をもっと短くします。 fQuesetDelayTime は数値を変えるだけで機能する特殊な変数で、他のスクリプトでもよく使われています。 fQuesetDelayTime に1を設定すると、そのクエストは1秒おきに処理が実行されます。指定しなければこれは4になっているので、1にすれば処理がもっとキビキビになるという訳です。 これは数字を小さくすれば、するほど処理が頻繁にされ遅延が減ります。例えば、set fQuesetDelayTime to 0.01 (0.01秒毎にこのスクリプトを処理する)などという事もできますが、冷静に考えるとそんな事をすれば処理が高負荷し、逆にゲームが重くなってしまう可能性があります。なので、そのスクリプトに合った処理間隔を指定してやったほうがいいと思われます。 fQuesetDelayTime を使うには、flort 変数で最初に宣言しておかないと使えません。
このMODのプログラムリスト
保存したespも置いておきます。
|