孙广东 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); } } // ... }
好了,就这样简单的任务代码 漂亮很多。也许是另一种方式吗?
如果你是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.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 是要自己控制的!
unity的 断言 Unity 5.1 Assertion Library
原文:http://blog.csdn.net/u010019717/article/details/50375226