unity3d教程:Coroutine不是这样用的

orientalfashion 发布于 2013/08/05 11:51
阅读 2K+
收藏 1
    昨天在测试的时候发生了很严重的当机事件,不管用什么Android的手机,在游玩过程中会不定时的无任何警示讯息自动跳出,从LogCat看讯息发现:

    1.ERROR/InputDispatcher(284): channel '418b6698 path.to.our.app (server)' ~ Consumer closed input channel or an error occurred.  events=0×8

    2.ERROR/InputDispatcher(284): channel '418b6698 path.to.our.app (server)' ~ Channel is unrecoverably broken and will be disposed!

    这时先冷静想想这几天加了什么东西?灵机一动,会不会是State Machine用Coroutine执行出了问题呢?来看看State在实做上的写法:

游蛮牛:http://www.unitymanual.com

using UnityEngine;
 
  
  using System.Collections;
 
  
  public class Script_Cube_Trigger_Terrain1 : MonoBehaviour {
 
  
  int Flag = 0;  //记录是否已经加载过该资源,避免多次加载
 
  
  //AssetBundleRequest abr;    <---- 刚才说的就是这里,暂时先不要用
 
  
  string debugstr = “”;    //调试信息
 
  
  static WWW wwwObj;        //每个场景中一个单独的对象
 
  
  void Start ()
 
  
  {
 
  
  if(Flag == 0)
 
  
  {
 
  
  //判断平台信息,如果是webPlayer就从网络上加载,如果是本地,就从本地资源目录中加载。
 
  
  if( Application.platform ==  RuntimePlatform.OSXWebPlayer || Application.platform ==  RuntimePlatform.WindowsWebPlayer )
 
  
  {
 
  
  //实例WWW对象,相当于从参数代表的网络地址上下载资源过程。
 
  
  //GlobalConfig.GetConnectIP()方法可以取得当前机器的全局IP地址(这个例子中,服务器端和客户端在同一台机器上)
 
  
  wwwObj = new WWW(“http://”+GlobalConfig.GetConnectIP()+“/AB/Terrain/Terrain1.unity3d”);
 
  
  }
 
  
  else
 
  
  {
 
  
  // 因为玩家是玩Web形式发布的游戏,所以本地没有资源,所以这里可以省略了,本地调试的时候可以打开用。
 
  
  // wwwObj = new WWW(“file:///E:/123/Terrain1.unity3d”);
 
  
  }
 
  
  }
 
  
  }
 
  
  void Update () {
 
  
  }
 
  
  // 当前对象(此例中就是那俩Cube)如果Collier的IsTrigger属性被勾选上了,那么当另一个Collier碰撞到此对象上,就会触发这个函数。
 
  
  void OnTriggerEnter(Collider other)
 
  
  {
 
  
  // this if-type hierarchy is just for simple debug, we can put debug message in each curly braces
 
  
  if(Flag == 0)
 
  
  {
 
  
  if(wwwObj!=null)
 
  
  {
 
  
  print(wwwObj.isDone.ToString());    //判断是否WWW对象已经下载完了
 
  
  if(wwwObj.assetBundle!=null)
 
  
  {
 
  
  if(wwwObj.assetBundle.mainAsset  !=null)
 
  
  {
 
  
  //load resouce into the assetbundle of wwwObject
 
  
  wwwObj.assetBundle.LoadAsync(“Terrain1”, typeof(GameObject));
 
  
  //创建地形实例
 
   //http://www.unitymanual.com/sitemapindex.xml
  if(Instantiate(wwwObj.assetBundle.mainAsset ) != null)
 
  
  Flag = 1;
 
  
  }
 
  
  }
 
  
  }
 
  
  }
 
  
  }
 
  
  // 调试用的,通过GUI来调试,可视化,蛮方便的
 
  
  void OnGUI()
 
  
  {
 
  
  GUI.Label(new Rect(0,0,200,200),debugstr);
 
  
  }
 
  
  }

    从上面看来原码在Compile上没错、也没有WARNING,不会有问题吧!殊不知,State在执行期间频繁的切换Start、Stop Coroutine的动作会让Andorid在不定时的状态下Crash,而且完全没有任何警讯!unity3d教程手册

    结论:

    如果你也有遇到相同的问题,请想想有没有甚麽地方跟我一样,在Class之间彼此不断的Start、Stop Coroutine,如果有!那可能就是Crash的关键。

    至于我怎么解掉这个问题的呢?方法很烂,我想大家因该都知道了,就是用void Update()来解决,不要自以为用Coroutine很屌。

详情参考:

Coroutine不是这样用的:www.unitymanual.com/thread-2210-1-1.html





加载中
返回顶部
顶部