unity的 断言 Unity 5.1 Assertion Library

来源:互联网 发布:淘宝上分期买手机 编辑:程序博客网 时间:2024/06/14 05:21

孙广东  2015.12.21


当你建立Unity 的手机游戏你最可能渴望设置Script Call Optimization为Fast But No Exceptions,只要你相信你能做到。
Fast But No Exceptions是隐藏在Edit -> Project Settings -> Player menu (Other Settings/Optimization section)。通过选择此选项您的代码将会去除异常处理代码,而得到更好的性能。通过启用此选项 你将带着很大风险。从现在起,任何异常会使你的游戏立即崩溃,你甚至不知道原因是什么。
你可能想要启用 Fast But No Exceptions选项,只有当你确信你的游戏不会抛出一个单一的异常。此外,如果你不是唯一的人在该项目中工作,风险就更大。
不要假设任何事情
不要假设你的脚本设置正确。要做一个悲观主义者,无时无刻都在想的最坏的情况。让我们以这个脚本为例:


public class Plane : MonoBehaviour {    public Airport airport;    void Update() {        if (Vector3.Distance(airport.transform.position, transform.position) < 1000) {            Land();        }    }    // ...}


这是一个非常基本的例子,关于如何与机场飞机进行交互。我想你已经知道要说什么。此代码如果没有Airport将会中断。这是,我们假设在场景工作的人会仔细,连接对象之间的所有引用的情况。但它不是那么容易,因为他们不连接的所有引用Unity不会给任何人的任何错误或警告,除非他们运行Scene,看到的异常。



好吧,我们试着让这个脚本更有自我意识。我们希望它有点毛病时发出声音。为了做到这一点,我将使用 MonoBehaviour.OnValidate() 消息
OnValidate() 被调用的情形是:

• 在 编辑器不需要进入play 模式
• 任何脚本值更改时
• 场景scene 加载时


因此,该脚本可能现在看起来像这样:

public class Plane : MonoBehaviour {    public Airport airport;    void OnValidate() {        if (airport == null) {            Debug.LogError("Airport is set to null", this);        }    }    void Update() {        if (Vector3.Distance(airport.transform.position, transform.position) < 1000) {            Land();        }    }    // ...}

这将打印错误消息到控制台,playing你的游戏在编辑器中,并在大多数情况下,这将是足够了。然而,你也可能想要在运行时 检查是否airport为 null (OnValidate()函数仅在编辑器中工作) 。

public class Plane : MonoBehaviour {    public Airport airport;    void OnValidate() {        CommonValidate();    }    void Update() {        CommonValidate();        if (Vector3.Distance(airport.transform.position, transform.position) < 1000) {            Land();        }    }    void CommonValidate() {        if (airport == null) {            Debug.LogError("Airport is set to null", this);        }    }    // ...}

好吧,你现在肯定在你的游戏中不抛出 任何异常, 使所有的验证过程造成一些 (小,但仍) 开销。如何摆脱它? 也许预处理器将帮助吗?


public class Plane : MonoBehaviour {    public Airport airport;    void OnValidate() {        CommonValidate();    }    void Update() {#if UNITY_EDITOR        CommonValidate();#endif        if (Vector3.Distance(airport.transform.position, transform.position) < 1000) {            Land();        }    }    void CommonValidate() {        if (airport == null) {            Debug.LogError("Airport is set to null", this);        }    }    // ...}


好了,就这样简单的任务代码 漂亮很多。也许是另一种方式吗?



Asserts(断言)的救援!

如果你是Unity 5.1  (或以上) 用户,那么你可以利用新的assertion library。它是真的很容易使用和内 Assert 类可能找到所有需要的函数。让我们使用它而不是简单的 null 检查。


public class Plane : MonoBehaviour {    public Airport airport;    void OnValidate() {        Assert.IsNotNull(airport);    }    void Update() {        Assert.IsNotNull(airport);        if (Vector3.Distance(airport.transform.position, transform.position) < 1000) {            Land();        }    }    // ...}


assert error message

正如你所看到的我使用 Assert.IsNotNull()。该函数告诉我期待值不为 null,如果它为 null,那么我想知道这件事。

Asserts 有手动检查的一些优势:
• 简单易读的代码
• 错误消息是 干净和 可读性强的 assert 错误消息
• 默认情况下断言在 non-development模式 (你不需要使用预处理器), building 游戏时就扒掉。

如果你想要 将asserts 列入您的build (断言不是由 默认的异常) 然后你需要做的一切是在脚本定义的符号,可以发现在Edit -> Project Settings -> Player的 Script Define Symbols 菜单中定义 UNITY_ASSERTIONS。断言不中断执行;资产将只打印错误和会继续执行。如果你想要它只是作为exceptions(中断执行),请确保从您的代码将 Assert.raiseExceptions 设置为 true。

记住,asserts 可能 在任意位置上使用您的代码 (它不一定要在Update ),但它是一个好的习惯,要尽可能检查尽可能多的事情之前执行的实际的代码。快速失败,安全!


。。。。


assert可以实现“三步一岗五步一哨”可以说是保证代码正确性(安全编程)的最有力工具。在用c++写程序的时候assert语句总是要占整个程序的大部分篇幅。

但是转到unityc#,一开始没找到assert,忍受了很长一段时间,今天好好google了一下,终于找到了。

unity5.1才引入的,参考:http://answers.unity3d.com/questions/19122/assert-function.html

下面是assert文档:http://docs.unity3d.com/ScriptReference/Assertions.Assert.html

但文档中建议不直接使用assert,而是使用MustExtensions,它是assert的一个可读性更好的封装。

MustExtensions文档:http://docs.unity3d.com/ScriptReference/Assertions.Must.MustExtensions.html

比如有一个变量n,我要断言:

(1) 断言n==0,可写成:

n.MustBeEqual(0,"nmust be zero!");

(n == 0).MustBeTrue ("n must be zero!");

(2) 断言n>0,可写成:

(n>0).MustBeTrue ("n must greater than zero!");

在使用Must前需要using UnityEngine.Assertions.Must;

断言和Debug的区别:

比较明显的是:

Unity对断言增加和封装了很多判断函数!

unity在发布的时候分为:release build debug  前者发布 会自动移除掉断言的, 但是Log 是要自己控制的!






1 0
原创粉丝点击