zoukankan      html  css  js  c++  java
  • Unityclient通信測试问题处理(二)

    Unityclient通信測试问题处理(二)


      在client的通信測试过程中。场景载入的问题给自己带来了不小的麻烦。由于消息的解析方法在单独的监听线程中调用,这也就意味着无法在消息的解析方法中调用Unity自身的API了。本来是打算在接收到场景切换的消息后,直接在解析方法中调用协同程序StartCoroutine。来实现场景的异步载入,但是如今一调用就会提示下面错误:

     

          StartCoroutine_Auto can only be called from the main thread...

         

         不能直接在监听线程中调用,那就仅仅能另想办法了。怎样来触发场景异步载入的协同程序呢?于是。自己想到了Start方法,由于这里是个调用协同程序的好地方。那么又该怎样调用Start方法呢?没错。通过对象的实例化来实现。

         当一个对象在实例化的过程中。它的脚本组件中的Awake方法与Start方法会相继运行。

    因此。我就通过实例化游戏对象的方式,来触发Start方法,进而在Start方法中调用协同程序。进行场景的异步载入操作。对象实例化的过程。通过一个布尔变量来进行控制,当解析方法中接收到场景切换的消息后,与目标场景相相应的布尔变量置为true,从而在Update方法中进行场景载入对象的实例化。代码例如以下所看到的:

     

         void Update( )

        {

            if ( _isLoginLevel ) {

     

                _isLoginLevel = false;

                InstantiateLoadLevelObject( LOGIN_LEVEL_NAME );

     

            } else if ( _isFirstLevel ) {

     

                _isFirstLevel = false;

                InstantiateLoadLevelObject( FIRST_LEVEL_NAME );

     

            } else if ( _isSecondLevel ) {

     

                _isSecondLevel = false;

                InstantiateLoadLevelObject( SECOND_LEVEL_NAME );

            } 

         }

     

         要实现这个过程,离不开Prefab的制作。我们须要针对项目中存在的几个不同场景,每一个场景制作一个Prefab,作为异步载入场景的对象使用,Prefab例如以下所看到的:

         


     

         然后还须要编写绑定在这每个Prefab之上的脚本,脚本实现的功能,就是依据不同的对象,来载入不同的场景,代码例如以下所看到的:

     

         void Start()

        {

            if ( LOGIN_OBJECT_NAME == gameObject.name ) {

     

                SceneMng.GetInstance()._isInLoad = true;

                StartCoroutine( SceneMng.GetInstance().LoadLevelAsync( SceneMng.LOGIN_LEVEL_NAME ) );

     

            } else if ( FIRST_OBJECT_NAME == gameObject.name ) {

     

                SceneMng.GetInstance()._isInLoad = true;

                StartCoroutine( SceneMng.GetInstance().LoadLevelAsync( SceneMng.FIRST_LEVEL_NAME ) );

     

            } else if ( SECOND_OBJECT_NAME == gameObject.name ) {

     

                SceneMng.GetInstance()._isInLoad = true;

                StartCoroutine( SceneMng.GetInstance().LoadLevelAsync( SceneMng.SECOND_LEVEL_NAME ) );

     

            } 

        }

     

         在协同程序中直接调用场景管理类写好的异步载入场景的方法。完毕场景的异步载入。异步载入场景的代码例如以下所看到的:

     

         public IEnumerator LoadLevelAsync( string levelName )

        {

            if ( null == levelName ) {

                yield break;

            }

            _async = Application.LoadLevelAsync( levelName );

            yield return _async;

        }

     

         通过以上处理。当我们在监听线程中的消息解析方法中接收到场景切换的消息后。就会马上实例化与目标场景相相应的游戏对象,然后通过在Start方法中调用的协同程序,来完毕场景的异步载入。

         自己仍然在琢磨,在Update方法中处理场景载入对象的实例化过程,这可能并非最佳的方式。若有不正之处或是好的想法。欢迎大家与我交流。



        本文出自杜晓萌的博客,未经特殊表明皆为本人原创,请勿用于不论什么商业用途。转载请保持完整性并标明出处:http://blog.csdn.net/haohan_meng


  • 相关阅读:
    非域,非匿名用户访问远程企业服务的详细步骤
    调用远程的企业服务的安全问题
    未能加载文件或程序集“****”或它的某一个依赖项的一种情况
    XAMPP使用非80端口的安装配置修改
    Lucene 的存储结构概述
    .NET Framework 4.0 SDK的安装
    lucene 文件存储相关的几个类
    ASP.NET 状态服务 及 session丢失问题解决方案总结
    不安装.net framework框架运行.Net 程序的方法<收藏>
    net面试题集及答案
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5350845.html
Copyright © 2011-2022 走看看