- Papyrusスクリプトの記憶を記録に残すシリーズその6 -
MOD導入後、初回だけ実行して魔法を覚えさせたいときなどの方法です。関連して、毎回ロード時に実行する方法もご紹介します。
目次
1. 初回ロード時だけ実行する
1-1. クエストの作成
ロード時にスクリプトを発動させるためには、クエストを新規で作成して使います。
Object Window の Character > Quest を開き、右クリックして「New」を選択すると新規クエストを作成できます。
IDを入力し、「Start Game Enabled」と「Run Once」をチェックします。Typeには「Miscellaneous」を指定します。
そして一旦「OK」を押して確定します。これをしないとクエストの大枠がきちんと作成されないようで、そのままスクリプトを付けようとするとCKが落ちます。
クエストを開きなおすと、次のようにタブがいくつか追加されているはずです。
1-2. クエストにスクリプトを付ける
作成したクエストの Scripts タブを開きます。「Add」ボタンを押して新しくスクリプトを作成するのですが、Extends のところを「Quest」にします。もし空欄になっていたら書き込んでから「OK」してください。
スクリプトのコードは以下のようにします。
Scriptname EkaFirstTimeScript extends Quest Bool booInit Event OnInit() Utility.Wait(0.1) If booInit == true Return Else booInit = true Debug.MessageBox("初回用スクリプトを実行しました。") EndIf EndEvent
Scripts タブに下図のようにスクリプトを付けられたら完成です。
これで初回ロードのときだけメッセージボックスを出すようになりました。必要に応じてその部分を改変してお使いください。
1-3. 分岐の補足説明
上記スクリプトでは、OnInit
イベントの仕様への対策としてBool変数を使った分岐をしています。OnInit
イベントは何故か同時に2回イベントを発動させることがあります。もしかしたら確実に実行させるための仕様なのかもしれませんが、メッセージボックスのように2回出て欲しくないこともあるので対策が必要です。
ポイントは「Utility.Wait
」です。Papyrusに限らず、スクリプトのウェイトコマンドというのはわずかに誤差が生じます。OnInit
イベントで同時に2つ発動した処理のタイミングを、ウェイトの部分でずらしているのです。
Bool変数は初期値が false ですから、先に If の Else 分岐に入った方がBool変数を true に書き換え、後から If に到達した方は Return の分岐に入って何も実行されません。
ちなみにこの2回同時発動は、スカイリムを起動して最初にセーブデータをロードしたときに良く起こります。2回発動する条件について確実な再現性が得られていないのですが、Bool変数を使って分岐していれば今のところ正常な動きをしてくれているので上記の方法をとっています。
2. 毎回ロード時に実行する
2-1. クエストの作成
セーブデータをロードするたびに毎回実行される方法です。先ほどと同様にクエストを新規で作成します。
IDにクエスト名「EkaEveryTime」を入れ、「Start Game Enabled」をチェックします。Typeには「Miscellaneous」を指定します。そして一旦「OK」して確定します。
2-2. クエストにスクリプトを付ける
作成したクエストの Scripts タブを開き、「Add」ボタンを押して新しくスクリプトを作成します。スクリプト名は「EkaEveryTimeScript」にしました。Extends のところは「Quest」にします。
スクリプトのコードは以下のようにします。
Scriptname EkaEveryTimeScript extends Quest Bool booInit ;--------------------------------------------------初回ロード用 Event OnInit() Utility.Wait(0.1) If booInit == true Return Else booInit = true Load() EndIf EndEvent ;--------------------------------------------------実行する内容 Function Load() Debug.MessageBox("毎回用スクリプトを実行しました。") EndFunction
ここでは初回ロード用の OnInit
を記述し、実行する内容を Function
という関数部分に書いています。
Function ~ EndFunction
の外から Load()
と記述することで、その内容が実行されます。「Load
」が関数の名前で、既存の関数名でなければ自由に付けられます。
Scripts タブはこれでOKです。さらに追加設定をしていきます。
2-3. クエストのエイリアスの設定
クエストにスクリプトを付けただけでは、毎回ロード時にそのスクリプトを実行することができません。
Quest Aliases タブに移動し、右クリックして「New Reference Alias」を選択します。
Reference Alias ダイアログが開きますので、次のように設定します。
Alias には適当に名前を付けます。Fill Type は「Unique Actor」から「Player」を選択します。
そして Scripts の「Add」ボタンを押して新しくスクリプトを付けます。スクリプト名は「EkaEveryAliasScript」にしました。Extends は「Alias」にしてください。
コードは以下のようにします。
Scriptname EkaEveryAliasScript extends Alias EkaEveryTimeScript Property QuestScript Auto Event OnPlayerLoadGame() QuestScript.Load() EndEvent
スクリプト名やプロパティ名がいくつか出てきて混乱しそうになりますが、間違えないようにしましょう。
プロパティにはクエスト本体を指定しますが、上記の通りにしていれば「EkaEveryTime」しか選択できませんので大丈夫でしょう。
スクリプトが設定できれば次のようになっているはずです。
確定して「Quest Aliases」が設定できていれば完成です。
あとはクエストに付けたスクリプト「EkaEveryTimeScript」の Function Load()
内にやりたい事を書き込めばOKです。
毎回ロード時に実行する方法は設定がやや複雑ですね。ほぼコピペで作成したほうが楽かもしれません。
補足:私はスクリプトを書くのは好きですが、専門家ではありません。内容は creationkit.com の情報と個人的な経験を基にして書いています。どうかご参考程度にご覧ください。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。