找回密码
 立即注册
查看: 6489|回复: 92

[优化测试] Unity3D性能优化 - Update() 的使用

[复制链接]
发表于 2012-11-28 10:12 | 显示全部楼层 |阅读模式
资源信息 Tutorial Information
教程名称: Unity3D性能优化 - Update() 的使用(发帖教程)
适用引擎:   (适用引擎,为空默认为Unity)
教程语种: 中文
教程等级: 1
教程格式: 图文(请用IE9以上浏览器访问本版块)
教程作者: 转载自互联网 (如有问题请短消息联系作者或发表回复)
下载地址: (兑换积分)
点击查看原图
美丽分割线

个人认为在脚本方面采用面向对象的调用开发,每次在Update里面写代码的时候,你要考虑,是否值得这么做,因为我们都知道update是每一侦都会执行的,那么如果有些代码并不是每次都需要调用的,你就不应该放到update里面检测某个条件成立,然后再执行,这样就类似C语言的过程式编程了。

不知道大家是否完全了解了官方这里http://docs.unity3d.com/Documentation/ScriptReference/index.Performance_Optimization.html 所说的一样去优化你的代码。特别最后一点就是强调update里面不要加入你没有达到的方法调用。

常见的update写法莫过于:

1、判断某个时间点、或者某个bool是否为true然后执行某些方法或者调用某个方法。


  1. [csharp] view plaincopyprint?
  2. 01.void Update()  
  3. 02.{  
  4. 03.    if( b == true)  
  5. 04.     {  
  6. 05.          ........do something....  
  7. 06.     }  
  8. 07.}  
复制代码
如上,应该很多人会这样写,因为读起来很好理解啊。其实这样就是掉入了消耗每一侦不必要的判断,想象一下这是一个人物身上的脚本,有N个人物,是否就要update里面N个脚本会判断N次,我好像很喜欢用N个人物来说事情,习惯了,谁叫每天看到最多的就是人呢!

那么如何解决呢???

大家仔细看我前面引用的官方文档里面最后那点,让你完全地使这个monobehaviour变成残废。其实就是这个脚本或者component变成enable = false; 你把b想象成你要在update执行的component的enable,如果它打开,那么update自然就启用了,否则让它整个脚本废掉!!!!!

所以官方提及了有2个方式:1、是否被渲染到这个物体(被摄像机照到);2、用触发器去检测和控制;


1.1 除了以上直接把这个component的enable关闭外,那么我这里需要强调就是coroutines的使用,特别是对于N秒后需要调用某些方式;或者按了某个键才做什么,否则直接返回;那么使用coroutines比你在update里面写个计时器或者判断某个键好多。

参考讨论:http://answers.unity3d.com/questions/119076/Coroutines-vs-UpdateFixedUpdateLateUpdate.htmlr


  1. [javascript] view plaincopyprint?
  2. 01.function Update () {  
  3. 02.    if (!wait) {  
  4. 03.       transform.Translate(Vector3.forward * Time.deltaTime);  
  5. 04.    }  
  6. 05.    else if (Time.time >= timer) {  
  7. 06.       wait = false;  
  8. 07.    }  
  9. 08.    if (Input.anyKeyDown) {  
  10. 09.       wait = true;  
  11. 10.       timer = Time.time + 1.0;  
  12. 11.    }  
  13. 12.}  
复制代码

ansform.Translate(Vector3.forward * Time.delt


以上很多人都可能会这么写,那么我们用协程如何操作了,可以StartCoroutine……


  1. [javascript] view plaincopyprint?
  2. 01.function Start () {  
  3. 02.    while (true) {  
  4. 03.        transform.Translate(Vector3.forward * Time.deltaTime);  
  5. 04.        if (Input.anyKeyDown) {  
  6. 05.            yield WaitForSeconds(1.0);  
  7. 06.        }  
  8. 07.        yield;  
  9. 08.    }  
  10. 09.}  
复制代码
那么我结合以上关闭这个component以及倒计时的使用,来实现我的目地:
因为我的update方法里面需要检测是否显示某个页面,然后某个滚动条的%需要实时获取数据来改变。关闭这个页面的时候,完全让这个脚本给取消enable = false; 但是我需要延时,因为你有可能临时关闭然后马上打开,那么可以减少这之间的瞬间变来变去的消耗,采用coroutine再也合适不过了!!
具体请看代码:

  1. [csharp] view plaincopyprint?
  2. 01.using UnityEngine;  
  3. 02.using System.Collections;  
  4. 03./// <summary>  
  5. 04./// Thinkgear user interface help message.  
  6. 05.///   
  7. 06./// By chiuan 2012.8.18  
  8. 07./// </summary>  
  9. 08.public class ThinkgearUIHelpMessage : MonoBehaviour {  
  10. 09.    //the time gap that need to disable the component .  
  11. 10.    const float _TimeToDisable = 0.2f;  
  12. 11.    bool isNeedToDisable = false;  
  13. 12.     
  14. 13.     
  15. 14.    #region for other call message or invoke.  
  16. 15.      
  17. 16.    public void UnActiveObject()  
  18. 17.    {  
  19. 18.        isNeedToDisable = true;   
  20. 19.        StartCoroutine("StartCheckDisable");  
  21. 20.    }  
  22. 21.      
  23. 22.    public void ActiveObject()  
  24. 23.    {  
  25. 24.        if(isNeedToDisable == true)  
  26. 25.        {  
  27. 26.            //because this means the coroutine has started.  
  28. 27.            //than u need to stop it,if u wanna active this .  
  29. 28.            StopCoroutine("StartCheckDisable");  
  30. 29.        }  
  31. 30.        isNeedToDisable = false;  
  32. 31.    }  
  33. 32.     
  34. 33.    #endregion  
  35. 34.      
  36. 35.      
  37. 36.      
  38. 37.    IEnumerator StartCheckDisable()  
  39. 38.    {  
  40. 39.        yield return new  WaitForSeconds(_TimeToDisable);  
  41. 40.        if(isNeedToDisable)  
  42. 41.        {  
  43. 42.            gameObject.SetActiveRecursively(false);  
  44. 43.        }  
  45. 44.    }  
  46. 45.}  
复制代码
以上UnActiveObject的方法是在这个页面要禁止时候由其他component控制调用,这时计时器coroutine开始启动,那么如果期间没有临时执行activeObject这个方法,那么这个页面将会延时disable,同时这个页面的所有component都会uncheck掉了!

1.2****延伸

大家可以使用OnEnabel()和OnDisable()方法检测这个脚本component是否活跃状态来执行初始化或者启动某些方式运算和关闭和清理工作。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
 楼主| 发表于 2012-11-28 11:55 | 显示全部楼层
认真的看下来会对你有帮助的
 楼主| 发表于 2012-11-28 11:55 | 显示全部楼层
求加精{:5_408:}{:5_408:}{:5_408:}{:5_408:}{:5_408:}
发表于 2012-11-30 09:21 | 显示全部楼层
我顶!!!
发表于 2012-12-3 09:52 | 显示全部楼层
我也顶、、、、、、、
发表于 2013-3-15 14:19 | 显示全部楼层
正在找这方面的资料
发表于 2013-4-11 00:33 | 显示全部楼层
这才是编程人员需要的
发表于 2013-6-11 10:07 | 显示全部楼层

我很懒,只想回复看看,另感谢楼主分享{:soso__16915934313317769624_2:}
发表于 2013-7-13 04:11 | 显示全部楼层

也不能一竿子打死呀!{:soso__11174995096617402082_3:}
发表于 2014-5-7 21:04 | 显示全部楼层
经验之谈,很有用。不是一般人能总结的出来的 ,求加精{:5_401:}
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-3-29 18:45 , Processed in 0.104331 second(s), 35 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表