文書の過去の版を表示しています。
エラーのお話
オダメで出力されるエラーについてのお話。
エラーを見れるようになる必要はないですがエラーに含まれている情報でどこが重要なのかを知れば、他者に聞くときに渡すべき情報がどれかのの判断の一助になるかもしれません。
コンソール(黒いあの画面)に出力されるエラーメッセージ
まず大きく2種類のパターンがあります。
- 個々の処理がエラーを捕まえて自分でエラーメッセージを出しているもの。
- 個々のエラー処理が例外を捕まえておらず、システム1)が出しているもの。
前者の「個々の処理がエラーを捕まえて自分でエラーメッセージを出している」のほうは、どういった動作をするかはその「個々の処理」次第であるため非常に有意義な情報を出してくれる場合もあれば、まったくなにも出さなかったり誤った情報を出す場合などもあります。
後者のシステムが出すものは、決まった内容を出してきます。
個々の処理が出しているエラー
役に立つ情報を出している場合もあれば、そもそも何が出しているのかわからないものもあります。
システム(Unityとかmonoの例外処理機構)が出しているエラー
正常に動作出来ない状況になった際に例外(Exception)が発生します。
これを捕まえ(catch)ずに放置すると見慣れたメッセージが出力されます。
こちらは決まったパターンで出力されます。
例えば最初の行
TypeLoadException: A type load exception has occurred.
「TypeLoadException」は例外の種類、続いてその説明「A type load exception has occurred.」。
次の「Stack trace:」の後にスタックトレースが続きます。
エラー(例外)の種類
何がまずかったのかを表しているためヒントになることが多いですが、よくある例外だと「まぁそうだろうね」ぐらいでしかない場合も。
よくある例外
- NullReferenceException
いわゆる「ぬるぽ」本来あるべきもの、本来取得できるものなどがない状態でそれを操作した場合など。
ほとんどの場合、操作することが問題ではなくあるべきものがない、取得できるはずのものが取得できてないないことが問題。
直前にファイルが読めてないとか出ている場合はおそらくそれが原因。
- FileNotFoundException
名前通りでファイルが見つからない場合に発生する。
ただしデータファイルに限らずDLLなどがない場合もこれになる場合があるので要注意。
- MissingFieldException
本来あるはずのものがない場合。2)
非常によくあるのが“TBody.goSlot”がないといわれるもの、COM3D2とCOM3D2.5でこの部分の扱いが変わっており、COM3D2用のプラグインをCOM3D2.5に入れたりすると発生する。
- TypeLoadException
これもあるはずのものがない場合。3)
これも同じで“Slot”がないよ!って言われるのはCOM3D2.5用プラグインをCOM3D2に入れた場合など。
スタックトレース
例外が発生した箇所までにどういった処理が呼び出されているかを示したもの。
最初の行(一番上の行)が最後に処理された箇所、つまり例外が発生した箇所です。
ただ、ここに問題があると言うわけではありません。
例えば渡されたメイドさんを××するという処理だとして、メイドさんが渡されなかった場合はここでメイドさんがいないんじゃぁ例外4)が発生しますが、その原因はメイドさんを渡さなかった直前の処理です。
その直前の処理もその前の処理が原因かもしれないのでどの処理が悪いかは単純に判断出来ません。
ただし、エラー発生に至るまでの処理がわかるので、その処理を行ったプラグインがぁゃιぃと言うような見当を付けることは出来ます。
バージョン不一致
プラグインインストール時になにかないと言うエラーが出る場合はバージョン不一致であることが多い。
- COM3D2用のプラグインをCOM3D2.5に入れている
- COM3D2.5用のプラグインをCOM3D2に入れている
- プラグインの想定に対してオダメのバージョンが古すぎる
- プラグインの想定に対してオダメがバージョンが新しすぎる
特に以下のものはCOM3D2とCOM3D2.5で異なっているので、COM3D2用とCOM3D2用.5用を間違えると出がち。
- Maid.MaidProp
- Maid.DelSubProp
- CharacterMgr.PresetSet
- ImportCM.LoadSkinMesh_R
- ImportCM.ReadMaterial
- TBody関連(典型的なのはTBody.goSlot)
- COM3D2環境でIsCrcBodyがないと出たらCOM3D2.5用を入れている可能性が大。
オダメバージョンアップ後になにかないと言うエラーが出る様になった場合は、プラグインが新しいオダメに対応出来なくなった可能性があるのでプラグインの作者に連絡するのもあり。
プラグインが使えなくなるからオダメのバージョンを上げないという選択肢は、オダメの新しいDLCが使えないだけではなく、新しく公開されたプラグインも使えない可能性があることに注意。
プラグインがオダメのバージョンで使えなくなる理由の例
今まで呼び出していた処理に渡さないといけないものが変更される。
処理(引数 a, 引数 b)だったものが、処理(引数 a, 引数 b, 引数 c)に置き換えられた様な場合。
この場合処理の名前は同じでも渡さないいけないものが異なっているので別物として扱われる、そのため元のものがなくそんなものはないよエラーになる。
処理結果等渡される値、返される値に想定外のものが追加される。
これの典型的な例はOnLevelWasLoadedでOnLevelWasLoadedに渡されるレベルに負の値が渡されるようになって、trzr氏のプラグインは負の値が来ることを想定して居らずエラーになっている。
enumの値が変更される。
これの典型的例はSlotがずれる、カテゴリーがずれるというやつ。
enumは例えば
enum SlotId { body, head, eye, }
と定義するとbodyは0, headは1, eyeは2と言うように連番を振ってくれるのだが、間に追加すると
enum SlotId { body, TNTN, head, eye, }
bodyは0のままだがTNTNの1が追加され、headは2, eyeは3とずれてしまう。
例えばプラグインで頭を大きくしようと MakeBig(head)5) の様に呼び出していると、コンパイル時に MakeBig(1) と置き換えてしまう。
(コンパイラーは実行時に都度名前から数値に置き換えのは無駄だとし、コンパイル時に確定してしまう。)
これを新しい環境で実行すると、1は頭じゃなくTNTNなのでTNTNが大きなってしまう。
この問題への簡単な対応は新しい環境でコンパイルし直すことで、コンパイルし直すとMakeBig(head)はMakeBig(2)なり正常に動作するようになる。
(ただし、これを古い環境で実行すると、2はeyeなのでおめめぱっちりになる。)
コメント