いんでぃーづ

ゲームいろいろ、いろいろ自由

デバッグに便利な UnityEngine.Assertions

Unity5.1 で UnityEngine.Assertions ネームスペースのクラスが追加になりました。

ゲームを動かしながら値の正当性をチェックできる便利な機能です。

基本の文法

使い方は簡単。

using UnityEngine.Assertions;

public class AssertionTest : MonoBehaviour {

    public int v1;
    public int v2;

    void Start () {

        // f1 と f2 が同じ値でなければエラー
        Assert.AreEqual(v1, v2);

    }
    
}
    

上のように UnityEngine.Assertions ネームスペースを using に定義し、Assertクラスのメソッドを呼べばよし!
正しくない値が入っていると、Console にエラーが表示されます。

f:id:sugar_affordance:20150616135645p:plain

上の画像のようにError Pause を有効にしていれば、エディターで再生している場合ポーズもしてくれます。

関数リストは元サイト参照。

Assert

大サービスでサマリーだけでも置いとくか!

関数名 用途
AreApproximatelyEqual 二つの値の差分が、引数の tolerance 以下(デフォルトは 0.00001f)だったらセーフ
AreEqual 同じ値だったらセーフ
AreNotApproximatelyEqual AreApproximatelyEqual の逆
AreNotEqual AreEqualの逆
IsFalse falseだったらセーフ
IsNotNull nullじゃなかったらセーフ
IsNull nullだったらセーフ
IsTrue IsFalseの逆

ビルドして動かす場合、デフォルトではDevelopmentビルドのみ有効になります。
(BuildOptions.ForceEnableAssertionsを設定しないかぎり)

ビルド設定に関わらずアサートを含めたい場合、Player Settings からUNITY_ASSERTIONSシンボルを定義すればよい。

f:id:sugar_affordance:20150616143730p:plain

Exceptionとしてキャッチしたい

Assertに失敗したときにExceptionとして処理することもできます。
その場合Assert.raiseExceptionsをtrueにします。

using UnityEngine.Assertions;

public class AssertionTest : MonoBehaviour {

    public int f1;
    public int f2;

    void Start () {

        // Exceptionをキャッチしたい場合はこの設定をする
        Assert.raiseExceptions = true;

        try {
            // float 値の比較
            Assert.AreApproximatelyEqual(f1, f2);
        }
        catch (AssertionException e) {

            // ログが表示される
            Debug.Log("Assert Exception Occur");
        }
    }
    
}
    

Floatの比較について

Float型の値を == で比較するのは絶対にやめましょう!
内部的に保持している値が微妙に違っていて、正確な判定ができない場合があります。
floatの一致比較ではMathf.Approximately関数を使うのがお作法です。
自分はこれが原因でバグに悩みハマりました(泣)

同じように、Assertion クラスでも、AreEqualでなく AreApproximatelyEqual を使うほうがいいんでないかなー

もっと簡単に書く方法

実は拡張メソッドが用意されており、別な書き方をすることもできます。

MustExtensions

using UnityEngine.Assertions;
using UnityEngine.Assertions.Must;

public class AssertionTest : MonoBehaviour {

    void Start () {
        Assert.raiseExceptions = true;
        GameObject test = null;

        // 拡張メソッドでの記述
        test.MustNotBeNull();

    }
    
}

上のように UnityEngine.Assertions.Must ネームスペースを using すると、変数からアサート関数が呼べてしまうのです!

好きな方法で呼んでね。


“Unity” and Unity logos are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere, and are used under license.


免責事項

当サイトの広告バナー、リンクによって提供される情報、サービス内容について、当サイトは一切の責任を負いません。

また、当サイトの情報を元にユーザ様が不利益を被った場合にも、当サイトは一切の責任を負いません。

すべて自己責任でお願いします。