フォロワーを含め、NPCにはデフォルトで着用する装備が設定されています。これらの装備品はインベントリ画面を開いても表示されず、ゲーム内では確認することができません。
デフォルト装備は Outfit という項目で設定されており、これは複数の防具が登録された装備セットです。今回は、この Outfit の仕様とスクリプトを使った操作について、まとめておきたいと思います。
1. Outfit とは
1-1. Outfit の指定
Outfit は、複数の防具を登録したリストです。Creation Kit (CK) では Object Window の Items > Outfit に分類されています。
これを Actors > Actor で定義されるNPCに設定すると、デフォルト装備となります。
Inventory タブの「Default Outfit」と「Sleep Outfit」がその設定で、Default の方が通常装備、Sleep の方が寝るときの装備となります。
1-2. Outfit として装備したアイテムの仕様
Outfit の機能で装備したアイテムは、インベントリ画面では表示されません。そのため、プレイヤーが取り去ることはできなくなっています。
アイテム項目ごと非表示になるため、複数所持していたとしても余剰分が表示されることはありません。内部的にはアイテムを所持している状態なので、スクリプトの GetItemCount() 関数を使えば、所持数を確認することができます。
1-3. Sleep Outfit の意義
Sleep Outfit は、NPCのAIである Package で Sleep 行動をとる際に適用されるようです。設定のないNPCも多いものの、300人以上は「DefaultSleepOutfit」が使われています。衛兵には「GuardSleepOutfit」が設定されています。
しかし、実際のゲーム内で着替えた姿を見ることは少ないと思われます。というのも、Default Outfit に設定がある場合、Sleep Outfit には着替えないことが多いからです。試しに Default の方を裸にすれば、Sleep を着用するのを確認することができます。
確実に着させることができないため、自作MODで Sleep Outfit を扱う際は注意した方が良いでしょう。設定は間違っていないのに実際は着替えない、という状況になりかねません。
2. 着用するタイミング
2-1. ロード画面を挟んだセル移動
NPCは Outfit をずっと着続けているわけではなく、そのNPCがいるセルにロード画面を挟んで進入した際、毎回着用処理が行われています。ここで言うロード画面というのは、黒い背景に3Dモデルが表示されるもので、単に黒い画面が短時間出るタイプのロードは含まれません。
フォロワーとして一緒にセル移動をした際にも、そのフォロワーに着用処理が走ります。フォロワーの処理については後述します。
例外として、対象のNPCと同一セルにいる状態のセーブデータをロードしたときには、そのNPCに着用処理は走りません。あくまでもセル移動に伴うロード画面の後に起こります。
2-2. フォロワーとのアイテム受け渡し
フォロワーとアイテムを受け渡す際にも、着用処理が走ります。アイテムを渡したり取り去ったりするごとに1度 Outfit を着用し、その直後に最適装備への切り替えが行われています。切り替えは一瞬で行われるため、Outfit の着用を目視することはできないでしょう。
フォロワーでないNPCでは、着用処理は走りません。スリ、もしくはスクリプトで強制的にインベントリ画面を開いて受け渡しをしても、何も起こりません。
2-3. 特定のスクリプト関数
次の3つの関数で、Outfit の着用処理が走ります。
- SetOutfit()
- AddItem()
- RemoveItem()
SetOutfit() は、Outfit を指定する関数です。この関数については後で詳しく述べますが、着用処理が2回同時に発動しています。Outfit に含まれる装備に何かスクリプトを設定する場合には、この2回同時発動を制御する必要があります。
あとの AddItem() と RemoveItem() は、アイテムの受け渡しになります。この関数は、対象がフォロワーかどうかに関わらず着用処理を走らせます。ただし、まれに着用処理が走らないこともあり、やや不確実です。間に EquipItem() 関数を挟んでアイテムを装備させると、確実に処理が走ります。EquipItem() 関数だけだと何も起こりません。
3. 着用時の動作
3-1. 基本動作
Outfit の着用処理が行われると、他の装備品を外して Outfit のみを装備します。インベントリに所持しているアイテムと関係なく、Outfit のみとなります。
3-2. フォロワーだけの追加処理
対象がフォロワーの場合、追加の処理が行われます。1度 Outfit を装備した後、すぐに最適装備に切り替わります。
フォロワーであるかどうかをスクリプトで判定するには、IsPlayerTeammate() を使います。これが true のNPCのみ、追加処理が走っています。
当然ながら解雇すると追加処理は行われません。フォロワー中に最適装備だったNPCが、別れてロード画面を挟むと元の Outfit に戻ってしまうのはこれが理由です。
4. Outfit 情報の取得と変更
4-1. Outfit を取得する
スクリプトで Outfit を取得するには、SKSEの GetOutfit() 関数を使います。これは ActorBase から取得するものなので、対象のNPCに GetActorBase() を使い、さらに GetOutfit() を使って Outfit を取得することになります。
次項に関係する部分なのですが、Actor からは取得できないことに留意しておいてください。
4-2. Outfit を変更する
これが1番書きたかったことです。
Outfit 情報がどのように保存されているのか、変更すると何が書き換わるのか、ということを説明していきます。かなり特殊でややこしいです。
スクリプトで Outfit を変更するには、SetOutfit() 関数を使います。これは Actor にも ActorBase にもかけることができます。
ここで、Actor と ActorBase の Outfit 情報を分けて考えておいてください。さらに、対象のNPCがユニークかどうかも分けて考えます。
ユニークでないNPCの場合は、Actor に SetOutfit() をかけないと変更されません。ActorBase に対して使っても、何も変わりません。ActorBase の Outfit を変更する方法はないようです。
ユニークでない Actor にかけると Outfit は変更されますが、その Outfit 情報を後から取得することはできません。GetOutfit() は ActorBase にしか使えないからです。
少し不便ではあるものの、逆に考えると ActorBase の情報は書き換わらないので、そこから Outfit 情報を取得して SetOutfit() すれば、いつでも元に戻すことができます。
次に、ユニークなNPCについてです。この場合、Actor と ActorBase とのどちらに SetOutfit() を使っても、ActorBase の Outfit が変更されます。この元情報が書き換わってしまうため、後で元に戻したい場合はどこかに保持しておく必要があります。
SetOutfit() を使うと Outfit の着用処理が走りますので、フォロワーでないNPCはその Outfit に着替え、フォロワーの場合は最適装備に切り替わることになります。
Outfit の変更についてまとめると以下のようになります。
- ユニークでないNPCは、変更後に着ている Outfit 情報を取得できないが、容易に元に戻せる。
- ユニークなNPCは、変更後の Outfit 情報を取得できるものの、元の情報が失われるので保持しておく必要がある。
4-3. 防具の消失について
SetOutfit() 関数を使った際、元々持っている防具が消失することがあります。私は鎧と小手で経験したことがあります。Outfit に含まれる防具でもなく、MODで追加した特殊な防具でもないのに、不定期に起こります。
この現象の原因は今のところわかっていません。再現性がなく、消失する条件を絞ることすらできていません。
ただ、アイテムが消失するというのは影響がかなり大きいですから、対策はしておくべきでしょう。現時点で有効と考えているのは、SetOutfit() の前にすべての防具を別のコンテナに移しておくことです。Set が終わったら、それらの防具をNPCに戻します。持ち物から防具のみを抽出するというのは少し負荷がかかるので、実際には RemoveAllItems() ですべての持ち物を移しておくのが良いかもしれません。
これらの方法は Set するときに一瞬だけ裸になってしまう問題がありますが、アイテムが消失するデメリットに比べればましかと思います。
Outfit について現時点でわかっていることをまとめてみました。画像がほとんどない記事になりましたが、最後までお読みいただきありがとうございます。
4 thoughts on “Outfit の仕様とスクリプト”
NPCのOutfitを設定したり取得したりするmodを作成中に、Actor と ActorBaseの使い分けで嵌ってしまっていたところ、こちらの記事を見つけ、とても役に立ちました。ありがとうございます。1つ質問ですが、フォロワーの「最適装備」というのは、どの変数のことを指すのでしょうか?
Wingerさん、こんにちは。
「最適装備」は、ゲームプレイ中、フォロワーに何らかのアイテムを渡したときに自動で着替える装備一式を指しています。フォロワーにデフォルト装備よりも防御力が高い、もしくは価格の高いアイテムを渡すとその瞬間に着替えますが、その現象を「最適装備に切り替わる」と表現しています。
これでご質問のお答えになっていますでしょうか?どこか分かりづらい部分がありましたらどうぞご遠慮なくご指摘ください!
なるほど、わかりました!ご回答から、いま自分が参考にしている
Outfit関係のmod(Simple NPC Outfit Manager)では、SetOutfit()関数を
使っているにも関わらず「3-2. フォロワーだけの追加処理」が発生しない
ことに気づきました。そして、なぜ発生しないのかについてもヒントを
頂いたように思います。eka. Post authorさん、ご回答ありがとうございます。
何かご参考になるところがあれば嬉しいです☆
ちなみにですが、フォロワー状態のNPCにSetOutfit()を使うと、内部的には毎回最適装備への切り替え処理が起きているはずです。これは装備時にログを残すアイテムを作って検証するとわかります。SetOutfit()の後にEquipItem()等で装備変更すれば、ゲーム内では最適装備への切り替えがなかったように見えます。
さほど重要な事ではありませんが、作成されるmodの処理に関係しそうであれば気にしてみてください。