Unity客户端通信测试问题处理(二)

在客户端的通信测试过程中,场景加载的问题给自己带来了不小的麻烦。因为消息的解析方法在单独的监听线程中调用,这也就意味着无法在消息的解析方法中调用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

时间: 2024-07-30 06:14:00

Unity客户端通信测试问题处理(二)的相关文章

Unity客户端通信测试问题处理(一)

最近在测试程序的通信模块时,遇到了一个问题:Unity的API函数只能在主线程中调用,而作为客户端程序,我单独启用了一个监听线程来接收服务端发送的消息,消息接收后的解析函数也由该线程一并调用.那么问题来了,在解析函数之中,我将不能调用Unity的任何API函数. 之前因为没有意识到这个问题,许多处理都是直接放在消息解析函数中做的,程序一经测试首先就报出了以下错误: CompareBaseObjectsInternalcan only be called from the main thread-

小梅科普:Unity客户端架构设计与网络游戏关键技术

目前利用Unity开发移动端游戏越来越多,不论是游戏公司还是独立开发者都需要在移动互联网时代发挥各自的技术优势,把自己的产品做到最好占领市场.本课程介绍的是基于Unity客户端框架设计以及关键技术3DAvatar换装和热更新技术实现以及Protobuf-net序列化和反序列化的运用,只有掌握了Unity开发的关键技术才能将其运用在游戏开发中,对于快速的开发游戏占领市场至关重要. 本课程以此项目的开发为讲解内容,以目前游戏开发的关键技术为依据,由浅入深循序渐进进行介绍,绝大部分的代码的编写都有相应

Unity里面的自动寻路(二)

接着我的 上一篇自动寻路文章,这一次我们就来学习一下与自动寻路有关的组件吧.Unity中与自动寻路相关的组件主要有两个:NavMeshAgent (  又称导航网格代理 ),Off Mesh Link( 分离网格链接 ).这两个组件的作用与使用范围是不同的,我们唯一可以确定的是我们必须烘焙地形,产生NavMesh(导航网格).因为导航网格决定我们的角色(带有导航网格代理的角色)活动的范围.NavMeshAgent组件需要附着寻路的角色身上,比如怪物,而OffMeshLink这个组件主要是用来构造

【Unity 3D】学习笔记二十八:unity工具类

unity为开发者提供了很多方便开发的工具,他们都是由系统封装的一些功能和方法.比如说:实现时间的time类,获取随机数的Random.Range( )方法等等. 时间类 time类,主要用来获取当前的系统时间. using UnityEngine; using System.Collections; public class Script_04_13 : MonoBehaviour { void OnGUI() { GUILayout.Label("当前游戏时间:" + Time.t

【Unity 3D】学习笔记二十六:unity游戏脚本(六)

在3D游戏世界中,任何一个游戏对象在创建的时候都会附带Transform(变换)组件,并且该组件是无法删除的,也不应该删除.在unity中,Transform面板一共有3个属性: Position  (位置) Rotation(旋转) Scale(缩放) 这三个值都是用来调整游戏对象在游戏界面中的位置,状态等相关参数. Position  (位置) 任何一个游戏对象的三维坐标都保存在Vector3容器中,该容器记录对象在X轴,Y轴,Z轴的坐标.一旦Vector33容器中的坐标发生变化,那么Sce

unity客户端与c++服务器之间的简单通讯_1

// 服务器 # pragma once using namespace std; # include <iostream> # include <string> # include <stdio.h> # include <winsock2.h> # pragma comment(lib,”ws2_32.lib”) # include “Tool.h” void main() { WSAData wsadata; SOCKET ListeningSocke

【Unity 3D】学习笔记二十九:游戏实例——简单小地图制作

任何的学习,光看不练是学不好的.所以这次就总结回顾下怎么制作MMROPG类游戏中的小地图.在MMROPG类游戏里,主角在游戏世界里走动时,一般在屏幕右上角都会有一个区域来显示当前游戏场景的小地图.主角在游戏世界里走动,小地图里代表着主角的小标记也会随之移动.那怎么实现咧? 首先需要确定两个贴图,第一个是右上角的小地图背景贴图,应该是从Y轴俯视向下截取主角所在的位置大地图.第二个就是主角的位置大贴图.在本例中,因为没有学习unity地图制作,所以地图用一个面对象代替,主角用立方体代替,使用GUI来

[Unity+Android]横版扫描二维码

终于解决了一个忧伤好久的问题,严重拖了项目进度,深感惭愧!一直被一系列的问题所困扰,然后又只能自己一个人摸索,也是一段辛酸忧伤史,现在小结一下上个月在做二维码的过程中所碰到的问题以及解决办法,现在庆幸终于解决好了,终于能将这个功能告一段落,一下小结也是分享一下Unity的某些"坑",让同行少走弯路,起码在二维码这方面应该会有所启迪,欣慰的是接下来几天终于可以做自己应该做的事情了! 效果图: 先小结一下碰到的问题: 1.Unity工程屏幕方向与Android工程屏幕方向要一致的问题 本来

Unity手游之路&lt;二&gt;Java版服务端使用protostuff简化protobuf开发

http://blog.csdn.net/janeky/article/details/17151465 开发一款网络游戏,首先要考虑的是客户端服务端之间用何种编码格式进行通信.之前我们介绍了Unity游戏前端使用protobuf的方法.今天我们来谈谈服务端如何使protobuf.游戏服务端语言百花齐放,除了比较传统的c/c++外,Java,Erlang,Python都有很多团队在使用. 今天推荐一下Java作为服务端开发语言.国内很多出色的页游和手游都是采用Java作为服务端语言的.比如<神曲