一篇关于Unity3D优化的文章,翻译脚本优化部分
原文地址http://www.unifycommunity.com/wiki/index.php?title=General_Performance_Tips
Scripting
- Are you using the right algorithm? Selecting the right algorithm for a task yields much better optimization than any other code tweaking you might do. Note that the best algorithm is not always the one with the lowest average complexity. For small datasets, it is often better to use a slow algorithm with a small setup cost than a smart one with high initialization cost. (Eg. one would use hashtables or binary search trees for large list of data accessed by name, but a simple list and linear search if you are only accessing a few elements. -- although .Net's HashTable class already chooses the most optimal method depending on your data in this case.)
- 这里不用说,当然逻辑要正确
- Keep your FixedUpdate functions as lean as possible. These functions can get called around 50-100 times a second per applicable script per object, so they are a good target to optimize. If there are things that need to be only done when the display is updated, put that code inside the Update function.
- If possible, disable scripts on objects when they are not needed. If you have a large level in your game and there is an enemy kilometers away, you can probably switch off its AI script until the camera gets closer. A good way to switch on and off objects is by using gameObject.SetActiveRecursively(false) and sphere or box colliders set as triggers.
- 如果可能,将GameObject上不必要的脚本disable掉。如果你有一个大的场景在你的游戏中,并且敌方的位置在数千米意外,这是你可以 disable你的敌方AI脚本直到它们接近摄像机为止。一个好的途径来开启或关闭GameObject是使用 SetActiveRecursively(false),并且球形或盒型碰撞器设为trigger。
- Beware the empty Update functions. When creating new scripts with the Assets menu, they include an empty Update() function. Remove it if you don't need it as it comes at a (rather light) performance cost. This performance cost applies to all overridable functions in MonoBehaviour scripts, with Update and FixedUpdate being the main targets.
- 删除空的Update方法。当通过Assets目录创建新的脚本时,脚本里会包括一个Update方法,当你不使用时删除它。
- Refer to a GameObject by the most logical component. One could theoretically write: someGameObject.transform.gameObject.rigidbody.transform.gameObject.rigidbody.transform, but there is a whole lot of needless work done there. If you want to deal with an object's Transform, refer to it in your script as such in the first place.
- 引用一个游戏对象的最合乎逻辑的组件。有人可能会这样写someGameObject.transform,gameObject.rigidbody.transform.gameObject.rigidbody.transform,但是这样做了一些不必要的工作,你可以在最开始的地方引用它,像这样:
private Transform myTransform;
private Rigidbody myRigidbody;
void Start(){
myTransform = transform;
myRigidbody = rigidbody;
}
- Coroutines are your friends. Coroutines have only a tiny overhead and can be preferrable to an Update method that is called all the time needlessly. For example, if you had a script to fade in and out a light on command, you could do the fading in a coroutine instead of in Update. That way, most of the time when the light is not fading, the script takes a minimum amount of performance. If the fading was done in the Update function, you would be inefficiently polling to see if there is fading to be done.
-
协同是一个好方法。可以使用协同程序来代替不必每帧都执行的方法。(还有InvokeRepeating方法也是一个好的取代Update的方法)
- Don't use methods which search for objects any more than is necessary. This includes methods such as GameObject.FindByTag() and GameObject.GetComponent(), as well as all the component convenience properties (transform, light, etc.). These methods are optimised to operate as quickly as possible, but they still have to search through all the relevant objects to find the one you want. The most important thing is to avoid calling search methods repeatedly in Update() or FixedUpdate(). Instead, call the method once, store its result in a member variable of your class, and then use the member variable to access it the next time you need it.
- 这里的重点是尽可能不要再Update或FixedUpdate中使用搜索方法,你可以像前面那样在Start方法里获得它。
- Don't use SendMessage() (or similar functions) if you don't have to. SendMessage() is at least 100 times slower than calling a function directly, and this number increases as more scripts and functions are available on the object. If you can find the script you need ahead of time, do so and then call the function directly.
- 不要使用SendMessage之类的方法,他比直接调用方法慢了100倍,你可以直接调用或通过C#的委托来实现。
- JavaScript's (and Boo's) duck typing takes a small amount of computation. In performance critical areas and when using JavaScript, try to explicitly say what types of variables you are using when declaring them. (Although this is often done automatically by the compiler through type inference, which is just as effective as specifying the type yourself, so your milage may vary)
- 使用javascript或Boo语言时,你最好确定变量的类型,不要使用动态类型,这样会降低效率,你可以在脚本开头使用#pragma strict 来检查,这样当你编译你的游戏时就不会出现莫名其妙的错误了。