Unity3D被设计为单线程的结构,即在主线程之外绝大多数API都是无法使用的,而AvosCloud所有数据通讯都是异步的,这样就产生了一些问题。

举例来说,角色获得了足够的升级经验,于是向服务器发送升级请求,然而在服务器返回成功的回调里,你没法显示一个恭喜升级之类的面板。因为这个回调不在主线程中。

此文就如何处理这个矛盾进行讨论。

思路

简单起见,此文以登陆为例。下面是必须的登陆调用。

// <异步调用前>
AVUser.LogInAsync(userNameStr, passWordStr).ContinueWith(t=>{// <异步线程内>AVUser loginUser = AVUser.CurrentUser;
});

在这段代码中,先做两个标记位置#异步调用前和#异步线程内,便于后续讨论。

<异步线程内> 无法执行UnityAPI。但是我们必然需要让玩家登陆之后,进入到游戏画面。

但是在<异步调用前>和<异步线程内>都可以访问共享数据。

那么核心思路就是,设置一个共享数据,它拥有三个状态,待机、等待和完成。

在<异步调用前>,将共享数据写为等待,在<异步线程内>,将此共享数据写为完成。

主线程要反复查询此共享数据,如果它处于完成态,则根据异步调用获得的数据,调用相关UnityAPI。并将其重置回待机。

方案实现

这个是我比较推荐,自己也在使用的方案。

主线程设锁
此方案的结构很简单,放哪里都可以,这里我放进自己的GameManager类中。

// ---------------------------------
// GameManager.cs
// ---------------------------------
// NOTE 此方法必须在主线程中调用
public void AsyncBeginWait()
{UIManager.Instance.WidgetWaiting.Show(true);lock(asyncWaitObj){asyncWaitObj.AsyncWaiting = true;}
}// NOTE 可在任何线程中调用
public void AsyncEndWait(Action callback)
{lock(asyncWaitObj){asyncWaitObj.AsyncWaiting = false;asyncWaitObj.AsyncWaitAction = callback;}
}void Update () {lock(asyncWaitObj){if(!asyncWaitObj.AsyncWaiting && asyncWaitObj.AsyncWaitAction != null){asyncWaitObj.AsyncWaitAction();asyncWaitObj.AsyncWaitAction = null;UIManager.Instance.WidgetWaiting.gameObject.SetActive(false);}}
}

将上述结构应用到登陆

// -----------------------------------
// SomeLogin.cs
// -----------------------------------
// #异步调用前
GameManager.Instance.AsyncBeginWait();
AVUser.LogInAsync(userName, passWord).ContinueWith(t=>{// #异步线程内AVUser loginUser = AVUser.CurrentUser;GameManager.Instance.AsyncEndWait(()=>{// TODO 任何UnityAPI相关操作});
});

首先调用AsyncBeginWait显示等待画面WidgetWaiting,等待画面也起到阻断用户输入的作用。

AsyncWaiting设为true,告诉主线程异步工作已开始。

在异步调用完成之前,让玩家等待小段时间。这个时间很难说,Avos的登陆大多在0-2秒内,也出现过长达10s的情况。

在数据请求执行完毕后,设置AsyncWaitAction回调。

随后异步线程执行完毕退出,到达下一个主循环时,GameManager的Update发现有新完成的消息,于是在主线程调用AsyncWaitAction。

方案特点

  • 代码简洁,数据请求到后续处理都在一起,便于阅读和复查
  • 借助匿名函数优势,获取相关数据时会处于最便捷的位置

其他方案

我最初的一个方案是事件队列,类似网游的消息协议,将每一个数据请求对应于一个事件。后来发现太庞大了,而且每必要,于是撤掉了。

PInvoke是否另一种方案?问题是需要对所有必要的UnityAPI进行封装,究竟效果如何,得有心人试过才知道了。

阅读原文:http://www.lolofinil.com/2014/07/14/unity_work_with_async_api/

Unity3D与AvosCloud网游开发实践 - 单线程U3D中的异步通讯处理相关推荐

  1. (转)火溶CEO王伟峰:Unity3D手机网游开发

    今天看到这篇文章,感觉很不错,尤其是那句"Unity3D的坑我觉得最严重的坑就是没有懂3D的程序员,把Unity当成Office用". 转自http://blog.csdn.net ...

  2. 火溶CEO王伟峰:Unity3D手机网游开发

    http://www.gamelook.com.cn/2013/11/135467 GameLook报道 / 11月2日下午,GameLook游戏开放日活动在上海正式举行,此次会议gamelook邀请 ...

  3. Unity3D教程:手游开发常用排序算法 -下

    五.堆排序(Heap Sort) 1. 基本思想: 堆排序是一树形选择排序,在排序过程中,将R[1..N]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小 ...

  4. 【UE4】网游开发中的RPC和OnRep(二)

    [UE4]网游开发中的RPC和OnRep(二) 本文转自我的公众号-游戏开发手账 转载请标明出处 搭配Multicast,让Server和所有的Client正常运转起来. 上篇遗留了什么问题? 上一篇 ...

  5. 【UE4】网游开发中的RPC和OnRep(三)

    [UE4]网游开发中的RPC和OnRep(三) 本文转自我的公众号-游戏开发手账 转载请标明出处 最后说说怎么用OnRep完成子弹的同步. OnRep 使用属性同步也能够完成Client和Server ...

  6. Unity3D手游开发实践

    本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述:架构设计.原生插件/平台交互.版本与补丁.用脚本,还是不用? ...

  7. (转)Unity3D手游开发实践

    作者:吴秦 出处:http://www.cnblogs.com/skynet/ 本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名吴秦(包含链接). (转 ...

  8. 关于Unity3D手机网游开发一些小看法

    它的知识技能和职责,我就不仔细说了,说细了有一点像招聘启示.他的主要职责虽然负责技术,但是也给产品决策和方向提供一些决策.他最主要的考核指标,就是经验很重要,最好主导或参与过一款网络游戏的开发.举个例 ...

  9. 网游开发的学习与杂绪

    乘着头脑有点思绪,又没有时间进行整理, 赶紧把想到的一些个人见解记下: 1, 在网络编程里, 宜多用组合, 少用继承. 组合更适用于分解数据以在网络因时因地制宜的通讯. 2, 封装包含对数据的隐藏,但 ...

最新文章

  1. linux 开机错误 Entering emergency mode. Exit the shell to continue.
  2. 二叉查找树 平衡二叉查找树 红黑树 b树 b+树 链表 跳表 链表
  3. uniapp怎么引入css_Uniapp怎么引入外部js
  4. python中用来回溯异常的模块_python中的异常处理使用说明
  5. JVM调优总结(一)
  6. svn:error use xcode-select to change
  7. java更改背景_java – 使用jquery更改menue的背景颜色
  8. 梦见计算机房,梦见未来家里有机房是什么意思?
  9. Android笔记 theme主题
  10. BTREE与其它索引的优缺点对比
  11. 微软给中国学生的特权:免费使用微软软件
  12. linux安装 treenms
  13. 计算机操作系统复习题
  14. HTML 使用字体图标 引入图标
  15. 【例题4-2 uva489】Hangman Judge
  16. 360P2建html网站,360 P2路由器密码怎么设置?
  17. 手机智能汽车钥匙来了, 汽车远程启动在手机上就能完成
  18. G. Columns Swaps(并查集)
  19. 【3D打印机】原来配置Marlin2.0这么简单,别说我没告诉你。
  20. 从零开始研发GPS接收机连载——9、跟踪调试之凤凰涅槃

热门文章

  1. mysql高可用集群MHA,PXC
  2. windows应用小技巧
  3. IPVS(也叫LVS)的源码分析之persistent参数
  4. php监听iframe加载完成,window_IE iframe的onload方法分析小结,判断iframe是否加载完成的完美 - phpStudy...
  5. WordPress博客系统搜索引擎优化seo全攻略方法
  6. 分组统计group by
  7. 商品列表页面 html,商品列表模板
  8. Vue移动端----页面旋转进入特效功能实现
  9. 组件分享之后端组件——一个简单且高度可扩展的分布式文件系统seaweedfs
  10. 自媒体平台的创作方式有哪些?自媒体平台的选择方法