2013/03/24

Critterの一生とPapyrusのログ(前編)

さて今日は、スカイリムの美しい大自然を満喫するのに欠かせない、虫や魚、鳥といったCritter(生き物)たちのしくみについて、いつもの如く長文を垂れ流したいと思います。
ちなみにおばちゃんは前作オブリビオンの頃から素材採集というものが大好きで、クエストそっちのけでキノコ狩りに明け暮れていて、一年以上もプレイしていたのにメインクエストは未だクリアしていない…という体たらくでありました。
そんなわけでスカイリムにやって来て、まず一番最初に感動したのは、蝶々やトンボ、サケといった生き物が捕れる!ということでした。
花やキノコなど植物の素材を集めるだけでも楽しかった採集の楽しさを、スカイリムでは対象にCritter(生き物)を加えることで、さらに進化させた…と言えましょう。
どんなに美しい大自然の景色も、採取できる生き物がいないと物足りないです。

ああ、こういう浜辺で釣りや潮干狩りができたら、もっと楽しいのにな……
ところで皆様は、サケとスローターフィッシュの違いとか、鷹とニワトリの違いとか、Critterとそうでないものの違いって、判別がつきますでしょうか?
いや、蝶とかトンボみたいに小さい生き物ならともかく、見かけだけだとCritterなのかそうでないのか、よくわからない生き物もいるんじゃないかと、ふと思ったりして……
まあ、CKを弄る方であれば、攻撃するとコンパス上に赤い印が点灯するようなクリーチャーはCritterではなく、見かけが虫だろうが魚だろうが鳥だろうが「Actor」に分類される代物だということはよくご存知かと思います。
あのソルスセイム島のアッシュなんちゃら…というキモいカマドウマでさえも、見かけは思いっきり下等生物、というか便所コオロギにしか見えませんが、アイツもCritterではなく、人間のNPC達と分類的には同じ「Actor」の仲間です。
ちなみにあのカマドウマが、Critter扱いのちっちゃなバッタとかだったら、たとえ足がもげようがお腹がポロンと取れようが、おばちゃんは喜んで佃煮にするレシピModなぞを作ってレイロフ君にしこたま食わせていたかと思います。
どうしてベセスダ様は、アレをあんな化け物にしてしまったのでしょうかねえ。
次こそは、採集しがいのある可愛い新規Critterが追加されることを祈ります。


ちなみに「Critter」の生き物と「Actor」との違いは何かと言えば……それはまあ、いろいろありますが、なんといっても一番大きな違いは、自分で状況判断するActor用のAIを搭載しているか否かなのではないかと思います。
「Actor」は、AIパッケージというものをセットしてやれば、勝手に辺りをうろついたり、ご飯を食べたり、自分にできる行動の中から最適な行動を選択して適当に振る舞ってくれます。
また攻撃されれば自動的に相手と敵対化して、臆病なタイプなら逃走を計りますし、相手と自分の実力を見比べて勝てそうだったら挑みかかっていったり、また勝てそうになくても突っ込んでいったり……とにかく状況に応じた行動をいちいち細かいところまで指示してあげなくても、AIが勝手に考えて行動してくれます。
しかし「Critter(生き物)」はそういったActorではなく、単なるアクティベーターであるため、予め用意された自動のAIは一切搭載されていません。
それなのに何故、プレイヤーが近づくと急に身をひるがえして逃げたり、夜になったらいなくなったり、生き物みたいな行動をするのかというと……それは擬似的なAIとして組まれた「スクリプト」が付いているからです。
ホニングブリューハチミツ酒醸造所近くの橋に設置されたCritterのSpawner(生成器)

Critterは「Activator」の一種で、スイッチのようなある種の『仕掛け』です。
Critterの生き物は、上画像のようなSpawner(生成器)と呼ばれるアクティベーターを介してスクリプト処理によってゲーム上に自動で生み出されています。
Spawnerとは、スポーンするもの……Critterを産み出す親のような存在です。
(※Spawnerはいろんな種類があります。上画像にあるようなのは単なる一例です。
またハチの巣や養蜂場など、Containerタイプのオブジェクトにスクリプトが付けられて、Spawnerとして振舞っているものもあります)
ちなみにSpawnerから生成されるCritter自身もまた、アクティベーターです。
Critterの活動の全ては、このSpawnerがゲーム上に読み込まれて「OnLoad」というイベントを迎えることから始まります。
とある場所(セル)に配置されたSpawnerが「OnLoad」された時…のイメージ図。

文章だけだとイメージがつかみにくいので、ビジュアルにしてみました。
(余計わかりにくかったりして……;)
まず、プレイヤーがSpawnerの配置されたセルに侵入してくると、Spawnerのデータが「OnLoad」されるわけなんですが……実はこの「OnLoad」というのは、プレイヤーがセルに侵入するたびに発生するというわけではなくって……まあ、それについては後で書きますので、詳細は後回しにさせてください。

で、この「OnLoad」というイベントが起こるタイミングで、Spawnerは活動を始めるわけなんですが、「OnLoad」されたからと言って、SpawnerはいきなりポコポコCritterを発生させるわけではなくて、まずはいろんな状況を見てCritterを生成すべきかどうかというチェックを入念に行っております。
第一のチェック項目としては、プレイヤーとの距離……これは予め設定された距離の範囲内にプレイヤーがいるかどうかのチェックです。
この範囲は、Spawnerにくっついているスクリプトの「fMaxPlayerDistance」というプロパティの値なんですが、蝶やトンボなんかですと、だいたい4000に設定されてるようです。
4000という距離がいかほどのものなのか、数字だけでは想像はしにくいかと思いますが……そうですね、ブリーズホームの玄関を入ったとこからまっすぐ、突き当たりの食器棚のある壁までの長さがだいたい1200程度なので、距離4000はその3倍強といったところです。
おそらくその辺りの数値が、視認できるかどうか、といったラインなのでしょう。
たとえ同じセル内にいたとしても、プレイヤーから見えないような遠距離にCritterを発生させても処理の無駄ですから……一定の距離内にプレイヤーが近づいてくるまではCritterは生成されないようになっているのだと思います。

さて、プレイヤーが指定の距離圏内に居た!ということが確認できると……今度はSpawnerは発生させるCritterが活動しても良い状況かどうかのチェックをします。
たとえば蝶やトンボ、ハチといった虫は、雨や雪の降ってる時には見かけませんよね。
でも水の中にいるサケやアビシアン・ロングフィンのような魚は関係なく泳いでます。
それから活動時間……黄色い蝶や青い蝶なんかは昼間はよく見かけますが、夜になるといません。代わりに辺りが暗くなると出現するのはホタルやルナ・モスです。
そういった、Critter達の特性に合わせた出現条件(これもSpawnerのスクリプトのプロパティにセットされています)をチェックして、条件にすべて当てはまっている、という確認ができたら、そこでようやくCritterを発生させる準備に入ります。

ちなみにこういったCritterの発生条件が合わず、ダメ出しが出てしまった場合はどうなるのかというと……SpawnerはCritterを生成できる条件が整うまで、しつこくチェックを繰り返す怒涛のループ処理に入ります。
たとえばSpawnerに「Onload」イベントが起こった時点で、まだプレイヤーが指定の距離以内にはいなかったとすると……SpawnerはいったんそこでCritterを発生させることを諦めますが、再び二秒後にまたプレイヤーが圏内にいるかどうかのチェックを始めます。
Critterの活動時間や天気などについてのチェック時も同じです。
条件が合わなかった場合、一旦はそこで生成を諦めますが、二秒待機してから再びチェックをして状況が変わっていないかどうか確認します。
そんなしつこく確認しなくても……と思ったりしますが、こういう常時チェックが入るからこそプレイヤーがその場でボーっと突っ立っていても、雨が止んで晴れてくると、岩場の影から蝶々がひらひら飛び始めたり、夜になって辺りが暗くなると、茂みからポッポッとホタルが光って出てきて「ああ、もうそんな時間なんだ。早く寝床を探さなくっちゃ」…とか思うような変化に富んだ自然の風情を演出できるわけなんですよね。
もちろんこのループ処理は、永遠にハマってえんえんとチェックを繰り返すことのないように、様々なシチュエーションでループから抜け出せるように対策が施されています。
SpawnerからCritterが生成されるイメージ図(蝶の場合)
お次はSpawnerからCritterが生成される過程を見てみましょう。
ところでCritterといってもいろいろ種類がありまして、一応基本的には似たような構造ではあるのですが、生成されてからの動きはそれぞれのCritterでちょっとずつ違います。
そんなわけなので、今回は『蝶』を一例として書いていますが、これがトンボだったり鷹だったりする場合は、また違った流れになりますので、あくまでCritterというものがどのようなサイクルで動いているのか、ざっくりイメージを掴むためのもの、と思ってお読み下さい。

さて、Critterが発生する条件がすべて整ってGOサインが出ると、Spawnerはまず現在発生しているCritterの残数を調べます。
SpawnerにはCritterを何匹まで生成するか、という数値が予めプロパティ(iMaxCritterCount)によって決められているので、Critterを無数にじゃんじゃん好きなだけ発生させる、ということはありません。
また、自分が産み出した我が子のCritterについてはしっかりその数を把握していますし、子供のCritterの方も、自分が捕まったり、殺されたり、あるいは消えることになった場合は必ず親のSpawnerに「自分は死んだよ」ということを伝えています。
そういうわけで、現在生き残っているCritterの数というものは親Spawnerには分かるようになってますので、今回はあと何匹生成すればいいか、という数を決めます。
たとえば合計3匹の蝶が生成されるように設置されている場合、前回の生成時に生まれた蝶がまだ1匹生き残っていたとしたら……今回生成するのは2匹、となるわけです。

生成するCritterの数が決まったら、Spawner母さんはその数だけCritterを出産し、Critterが生きていくのに必要なCritterのクラスだのプロパティだのを我が子につけてやります。
生まれたばかりのCritterは、まず自分が動き回るために必要なlandingMarker、dummyMarkerといった着地地点用のマーカー類を準備しなくてはなりません。
そしてこの着地マーカーを使って、まず最初の移動(ワープ)を行います。

一般的な蝶の場合ですと、移動する時の着地点は「AAAMothPlantTypes」というFormListに登録された34種の植物とマーカーから候補を探すように設定されています。
蝶はよくツンドラの綿とかラベンダーの花の辺りに止まっているのを見かけるかと思いますが、あれは「AAAMothPlantTypes」というフォームリストに登録されている植物だからこそ、蝶が羽根を休める場所として着地点に採用されているわけです。
ちなみにこういった着地点は、親Spawnerから貰った「fLeashLength」というプロパティの範囲内で探すように決められています。
つまり母さんからあまり離れたところまで飛んでいったりしないように、手綱(Leash)をしっかり握られているわけですね。
その手綱の範囲内で、子供のCritterの蝶は自分が止まれる植物(あるいはマーカー)のターゲットを見つけ、初回はその地点に直接ワープします。
蝶Critterは、周囲の状況を逐一チェックしながら活動します。
うまく最初の着地点にワープした蝶Critterは、「AtPlant」という状態(State)にあります。
蝶CritterはいろんなStateを持っておりまして、状況に応じてこのStateを切り替えて活動してるんですが、植物の間をひらひら移動するサイクルを繰り返している時はこの「AtPlant」というStateの状態にあります。
「AtPlant」というStateの時は、次の着地点となる植物を見つけて、そちらに飛び移る、という動作を繰り返すのですが、その際に近くにActorがいないかサーチして、もし誰かを見つけたら、通常よりも早いスピード(逃げる時のスピード)で移動します。
また移動が完了した後も、通常なら5~10秒の間、植物に止まった状態で待機するのですが、誰かが近くにいたら、すぐさま次の植物に向かって飛びます。
(次の植物が見つかれば…の話ですが)
こういったチェックを常時行うことで、あたかも蝶が周囲の生き物を警戒して逃げ惑うような生き生きとした動きを再現しているわけです。

ちなみに蝶Critterが逐一チェックしているのは、周囲に誰かいるかどうかだけではありません。プレイヤーと自分の距離についても、逐一細かくチェックしています。
これは前述したSpawnerの時と同じで、プレイヤーがちゃんと「fMaxPlayerDistance」という距離の圏内に入っているか確認し、もし視認できないような遠くにいる場合は、即座に自分自身と関連する着地マーカー類を消去する一連の削除処理を実行するためです。
また、お天気や活動時間などの、自分が活動していても良いかどうかの状況チェックも、同じようにその都度行われています。
お天気が変わったり、活動時間外になると、Critterは「KillForTheNight」というお休みモードに移行して、自分自身と関連物を消去する削除処理に入っていきます。
この削除処理(disableAndDelete()という関数の処理)は、Critterをアクティベートして採取したり、また攻撃したり魔法を使ったりして殺したりした時にも実行されている処理です。
またプレイヤーがCritterの居るセルからプレイヤーが出ていってしまった時などにも実行されていまして、Critterが無駄にいつまでもしぶとく生き残っていたりしないように、何かイレギュラーなことがあればすぐに削除されるようになっています。
そんなわけで、Critterの一生というものは実に短くて、せっかく生まれても、大抵はプレイヤーが遠くにいってしまったりセルから出ていってしまったり、何かあればすぐに消されてしまう、はかない命だったりします。
もっとも幽霊になって、しぶとくデータに残ってる奴もいたりするようなんですが……これは一寸の虫にも五分のスクリプト…という奴なんでしょうかねえ。

それから、これはちょっと通常の蝶では見られないモードなのですが、蝶Critterには「FollowingPlayer」という面白いモードがあります。
たとえばDLC第一弾のDawnguardで、カンティクルの木の樹皮を持っていると聖蚕の蛾がたくさんプレイヤーの周りに群がってきましたよね。
おばちゃんはあの蛾にたかられた時はうひゃあ、という感じだったのですが……あれは「カンティクルの木の樹皮」を蝶Critterの好むアイテムに指定してあって、そのアイテムを持っているせいで蛾たちは「FollowingPlayer」のStateに移行してたわけです。
この「FollowingPlayer」というStateでは、いつもは人が近づくと逃げる蝶が、わらわらとプレイヤーの周りにたかってくるようになります。
これをいろんなCritterに悪用したら……と考えると、想像するだけで怖いですね。


さて、Spawnerの働きからCritterの活動内容といった概略を、かなり大雑把にまとめてみたのですが、いかがでしたでしょうか。これでも端折れるところはバッサバッサと9割方カットしたつもりだったんですが、後から読み返してみるとやはり無駄に話がクドくて読みにくいですね……ほんとお疲れ様でした。
それでも、Critterがいったいどういうタイミングで「発生」し、どういったタイミングで「消滅」していくものなのか、まずそれを知らないことには、Papyrusのログを分析することなんかできませんのでね。
そもそもおばちゃんがCritterの仕組みを調べようと思ったきっかけは、先日ソルスセイム島から我が家のレイクビュー邸に久しぶりに戻った折に、CTDしたことが発端なんです。
まあ、そのCTDは別にCritterのせいというわけじゃなくて、ゲームを再起動しなおしたら、もうCTDしなくなっていたので、たぶん何かのタイミングが悪くて落ちちゃっただけだと思うんですが、それでもPapyrusのログを見てみたら……Critterとおぼしきエラーがわんさか出ていまして。
確定CTDが起こるような致命的なエラーじゃないとはいえ、マイホームの周りでこんなわけのわからんエラーが仰山出てると、さすがに心配になりましてねえ。
それでとりあえず、Critterとはどんなしくみで動いているものなのか、わからないとログを見てもさっぱりなので……こうしてCritterとがっつり取っ組み合うことにしたんでした。

ちなみに我が家の周りに憑りついた幽霊Critterとの格闘の話は、長くなりましたので後編に回したいと思いますが、その前にSpawnerの説明の折に触れた「OnLoad」イベントについて少し補足したいと思います。
なにしろ「OnLoad」イベントはCritterの「発生」の鍵を握る重要なポイントですので、このイベントがどのタイミングで起こるものなのか、ということを把握することは大事です。
それではちょっとした実験をして、「OnLoad」イベントとはなんぞや、ということを確認してみましょう。
まずはブリーズホームの暖炉脇に蝶を一匹だけ生成する「Spawner」を配置します。
配置するのはSpawnerだけでなく、ラベンダーやランディングマーカー(CritterLandingMarker_Small)といった「AAAMothPlantTypes」のFormListに登録されている着地点用のオブジェクトもその辺に一緒に設置しておきます。
一匹の蝶が動き回るためには着地するポイントが最低でも2点は必要ですからね。
では準備がすんだら、このModを導入して、ブリーズホーム内でセーブしたデータから、ゲームを始めてみることにしたいと思います。
ゲームがロードされた直後のブリーズホーム。

ゲームをロードして室内を見てみると、配置したラベンダーはきちんと出現していますが、蝶の姿はどこにも見えません。
Spawner自体はもともと外観は無いので、見えていなくて当然なんですが……ラベンダーが反映されているということはMod自体の導入は成功しているということですよね。
ですからSpawnerも姿は見えなくてもきちんと暖炉の脇に配置されているはずです。
それなのに、いったいどうして蝶は生成されなかったのでしょう?

ちなみに、ここでブリーズホームから一旦外に出ると、おばちゃんの環境ではここで必ずロード画面が発生するわけなんですが、そのロード画面を挟んで再び室内に戻ってくると蝶がちゃんと生成されています。
壺が転がっているのは、舞い上がった蝶がぶつかったためです。
蝶の当たり判定って、パないですね(笑)
ちなみにスクリプトの各処理にデバッグ用のコメントをつけて、ブリーズホームの出入りの時の状況を書き出してみたPapyrusのログはこんな感じです。
[03/17/2013 - 00:00:09PM] Papyrus log opened (PC)
[03/17/2013 - 00:00:09PM] Update budget: 1.200000ms (Extra tasklet budget: 1.200000ms, Load screen budget: 500.000000ms)
[03/17/2013 - 00:00:09PM] Memory page: 128 (min) 512 (max) 76800 (max total)
[03/17/2013 - 00:00:17PM] VM is freezing...
[03/17/2013 - 00:00:17PM] VM is frozen
[03/17/2013 - 00:00:17PM] Reverting game...
[03/17/2013 - 00:00:20PM] Loading game...
[03/17/2013 - 00:00:20PM] VM is thawing...
[03/17/2013 - 00:00:30PM] ★Spawner[critterspawn < (02000D66)>]がonCellDetachされました
[03/17/2013 - 00:00:30PM] ★Spawner[critterspawn < (02000D66)>]がonUnloadされました
[03/17/2013 - 00:00:38PM] ★Spawner[critterspawn < (02000D66)>]がOnloadされました
[03/17/2013 - 00:00:38PM] ★Spawner[critterspawn < (02000D66)>]ShouldSpawn()を実行します
このログを見ると、面白いことに、最初に「OnLoad」はされなくても、ブリーズホームを出た瞬間に、Spawnerに「onCellDetach」と「onUnload」イベントがしっかり発生していることがわかります。
ですから外観は無いので見えないですけども、セーブデータがロードされた時点で、「Spawner」自体は確実にブリーズホームのセル内に読み込まれて存在していたわけです。
しかしセーブデータからロードしても、プレイヤーが最初からブリーズホーム内にいる状態では「OnLoad」というイベントは発生しなかった……
セーブデータから「ロード」したんですから、「OnLoad」されても良さそうなものなんですが、プレイヤーがそのセルにいる場合はどういうわけか「OnLoad」はされない……みたいなんですね。
理由はわかりませんが、そういう仕様なんだ、と解釈するしかありません。

ちなみに一度外に出てロード画面を挟んでから、再びブリーズホームのセルに侵入することで、ようやく初めての「OnLoad」状態が発生するわけですが……どうやらこの「OnLoad」というのは二回目以降も、ロード画面が発生した後、Spawnerの配置されたセルにプレイヤーが初めて侵入する時にしか発生しないようなんです。
つまり何が言いたいのかというと………次に蝶が新たに生成されるのはまた、Spawnerが「OnLoad」されるタイミングなんですが、この「OnLoad」という状態はどういう状況になったら起こるのか、と言いますと、ロード画面を発生させた後、Spawnerの配置されたセルにプレイヤーが別セルから初回侵入する時…というタイミングなんです。
ですからたとえば、ブリーズホームにいる蝶を全部獲ってしまって、再び室外に出ても、ロード画面が発生しない限りは蝶が再び生成されることはありません。
室外に出て、一度セーブして、それからそのデータを「ロード」して、ロード画面をしっかり拝んでから改めて室内に戻れば、蝶は新たに生成されています。
(セーブしなくても街の外に出るなどして強制的にロード画面さえ挟めばOKです)

今まで、蝶やハチやトンボは、植物と違って一日ぐらい経つとすぐにリスポンしているよな…とは思っていたんですが、まさか一日どころかロード画面を挟むだけで復活していたとは思いませんでしたねえ。
もっともプレイヤーがSpawnerと同じセルにいる場合は、ロード画面を発生させても「OnLoad」されることはないので、それでその法則にはなかなか気が付かなかったのでしょうが。
そう考えると、この仕様はゲームを中断した際に前後の状況を矛盾しないようにするための処置なのかもしれませんね。

Critterの一生とPapyrusのログ(後編)に続く

10 件のコメント:

  1. アルゴニアンの吟遊詩人2013/03/24 23:16

    一寸の虫にもキナレスの魂。
    目に見えないだけでエイドラはちゃんと世界に存在するんだなぁと思ってしまいました。

    普段何気なく採取してる蝶々たちがこんなにも入念な環境で表現されているとは、全く考えもしませんでした・・・
    バニラの時点で恐ろしく自然な表現になってますし、べセスダさんの拘りぶりが半端ないですねえ。

    それにしても、大自然の生き物(critter)達がキナレスの眷属だとすると・・・
    「Hearthfireのスクリプト回し」の記事に出てきた植木鉢の中の小人さんは、豊穣の神マーラのしもべ達なんじゃないか。
    と考えてしまい、小人のキャラがますます濃くなってしまいました。

    返信削除
    返信
    1. ほんとに、Critter関連のスクリプトは、たかが虫風情によくぞここまで入魂したよなあと呆れるくらいの出来です。ヘタしたら、かのセラーナ嬢が単細胞に見えてくるぐらい……

      Hearthfireの植木鉢の小人さんは、以前肥沃土のテストをした際に、面倒なので別セルではなく家の中に配置したことがあるんですが(一応見えない場所に配置したんですが)、玄関入ったらふんどし一丁のおじさんが所在なさげにウロウロしてて、ギョっとしたことがありました。
      小人さん…と書くと、妖精みたいで可愛いですが、実際に目撃すると変質者にしか見えませんね(笑)

      削除
  2. 公式だけではなく、これはっと思ったMODなんかもそうなんですが
    これどうやってるのかな?と思うところのscriptは
    調べてると気づかないうちにとんでもない時間になってますよね。
    発売後これだけ経ってるのに、未だにあちこちに驚ける部分が転がってる作品ってのはすごいと思います。国産ゲームでもこういうの欲しいな…。

    ちなみに私はOblivionのメインクエスト完了は一度だけですね、陛下には数え切れない位逢ってるんですがw

    返信削除
    返信
    1. 本当に…発売からもう一年半近くもたつのに、いまさら、ゲーム内ではありふれた存在のCritterにこんなに感心させられるなんておかしいですよね。
      でも今まで何百時間も遊んできたからこそ、感激もひときわなのかもしれません。
      ああ、こんな些細なものにまで、ここまで手間のかかりそうな仕組みを用意してくれていたのかって……
      それにしても、こういった「仕組み」を出し惜しみせずにユーザーに見せてくださるベセスダ様の心意気には本当に頭が下がりますね。

      > Oblivionのメインクエスト

      私も一度くらいは、Oblivionの竜神さまを拝みたいです……
      でも素材集めと料理Modでご飯作るのが楽しすぎて……いつもそれで終わっちゃうんですよねえ。

      削除
  3. そういえばほら吹きムアイクのセリフに
    「スカイリムにはかつて蝶がたくさんいた、今はそれほどいない。」っていうのがあったなぁ・・・
    一時はCritterの数が増えすぎて大変だったっていう製作者のぼやきだったんですかねぇ・・・(苦笑)

    個人的にイメージ図とても良い出来だと思いますよ!
    このイメージ図がないと具体的なイメージが正確に掴めなそうです・・・(汗)

    返信削除
    返信
    1. > スカイリムにはかつて蝶がたくさんいた、今はそれほどいない。

      それ、すごく意味深なセリフですね。
      なんかスクリプト見てると、これって実際は実装されてるのかな?と思うところが多々あったりするんですよね。
      もしかして開発当初はそのつもりだったけど、各方面と調整した結果、機能が削られて、残骸だけが残ってんじゃないかとか……
      まあ、私はド素人なのでテクニカルなことはまったくわかんないんですけども。

      それにしても、Critterのエラー、ほんとヤヴァイです。
      いろいろ実験してたら、ドツボにはまりつつあります……

      削除
  4. Knight-HawK2013/03/28 0:06

    イメージ図、すごく解りやすいです。CK見てて混乱して投げ出した部分もこんな感じなら理解できそう…。
    しかし、その辺を飛んでる蝶々やウサギや狐さんはこんなに複雑な処理で生み出されてたんですね…。
    しかも、プレイヤーが周りにいないと処分されてしまう存在…まぁ、処理負荷考えると仕方ないんですけど儚いですね~。

    ちょっとずれた話になるんですが、ブリーズホームの実験の結果を見るとプレイヤーが目の前にいると、オブジェクトが生成されても表示されない可能性が高いって事ですよね。
    という事は給仕人MODとか作ろうとしても、給仕人NPCがマーカーに乗ってフラグを立てた時に(予め配置しておいてDisableしておいた)料理を出現させるなんてのは、プレイヤーが同じセルにいるとうまく動かないんでしょうね。
    でも、NPCの巡回パッケージもプレイヤーが近くにいないと実行されないのでフラグ立たないし…。
    まぁ、違う所でアクティベータを操作して出現させておけば、食卓に向かった時には料理がある…って風にできますけど、それだと給仕人要らないんですよね…。^^;

    返信削除
    返信
    1. プレイヤーが同じセルにいる時に働かない処理というのは、あくまで「セーブ」して「ロード」した時の「OnLoad」の処理なので……「OnLoad」に頼らないトリガーであれば、大丈夫なんじゃないかと思います。
      「OnLoad」のようなタイミングで処理がしたい、ということであっても、「OnCellAttach」を使えばいいだけのような気がしますしね。
      給仕人でしたら、プレイヤーが注文するダイアログから、一度奥に引っ込んで戻ってくる給仕のシーンをスタートして、そのシーンの終了時にテーブルの上にあらかじめdisable状態で置いてあった料理のRefをenableにする、といった流れにすればいいのではないかと思います。

      ところで昨夜、ついにというか、ようやくというか……Critterのエラーの起こる原因を突き止めましたよ……(あくまで一ケースの場合に過ぎませんが)
      しかし、どうやって説明すればいいのやら……
      また変てこりんなイメージ図でも書いて、がんばって駄文を書き連ねるしかなさそうです。

      削除
  5. 光の筋が差し込む森の奥たくさんの蝶々に囲まれて、
    優しげな微笑みを浮かべる腕毛モッサモサの夢見るオッサンどばーきんという幻想的なSSを撮るのが目標だったんですが、
    こちらが近づくと一目散に飛んで逃げて行くので断念しておりました。

    Scriptで何かしないとならないというのはなんとなーく予想が付いても、
    それが実際にどの部分のどの処理なのかという点を探すだけでも自分程度の知識だと大変な時間を要します。
    Script弄りになるとまだまだ敷居が高すぎて行動に移すとなると随分先になりますが、
    FollowingPlayerを利用すればそれも可能になると、それが分かっただけでもありがたいです!

    返信削除
    返信
    1. お返事が遅れてしまいまして申し訳ありません。

      群がる蝶の中でたたずむ腕毛モッサモサ(笑)……実現しましたらぜひそのSSを拝見したいです。
      そういえば、リフテンのタロス像には蝶の着地マーカーが沢山設置してあるので、蝶々がタロス様を慕うように頭の上に乗ったりするんですよね。あれも結構、幻想的な眺めだと思いました。
      あの着地用のマーカーをうまく利用できたら、手乗り蝶々とか作れるのかもしれませんね。

      削除