如何评价unity3d unet5中多人游戏和网络模块UNet

个人学习(3)
转自游戏蛮牛
前段时间,研究了一下UNet,经过项目实践,大致整理了下遇到的。
  源码Bitbucket : (https://bitbucket.org/-Technologies/networking)需要说明的是,这个项目只包含上层的包装,一些低层的网络实现在Unity内部,如NetworkTransport类等并不包含。
  UNet常见概念简介
  Spawn:简单来说,把服务器上的GameObject,根据上面的NetworkIdentity组件找到对应监视连接,在监视连接里生成相应的GameObject.
  Command:客户端调用,服务器执行,这样客户端调用的参数必需要UNet可以序列化,这样服务器在执行时才能把参数反序列化。需要注意,在客户端需要有权限的NetworkIdentity组件才能调用Command命令。
  ClientRpc:服务端调用,客户端执行,同上,服务端的参数序列化到客户端执行,一般来说,服务端会找到上面的NetworkIdentity组件,确定那些客户端在监视这个NetworkIdentity,Rpc命令会发送给所有的监视客户端。
  Server/ServerCallback:只在服务器端运行,Callback是Unity内部函数。
  Client/ClientCallback:同上,只在客户端运行,Callback是Unity内部函数。
  SyncVar:服务器的值能自动同步到客户端,保持客户端的值与服务器一样。客户端值改变并不会影响服务器的值。
  上面的大部分特性都会转化成相应的MsgType,其中服务器调用,客户端执行对应MsgType有如Spawn,ClientRpc,SyncVar对应的MsgType分别为ObjectSpawn,Rpc,UpdateVars,这些都是NetworkServer调用,客户端得到相应消息,执行相应方法。客户端调用,服务器执行的MsgType有如Command,客户端发送,服务器检测到相应消息后执行。
  UNet主要类介绍
  NetworkIdentity组件介绍:网络物体最基本的组件,客户端与服务器确认是否是一个物体(netID),也用来表示各个状态,如是否是服务器,是否是客户端,是否有权限,是否是本地玩家等。
  一个简单例子,A是Host(又是服务器,又是客户端),B是一个Client,A与B分别有一个玩家PlayA与PlayB.在机器A上,playA与playB isServer为true,isClent为true,其中playA有权限,是本地玩家,B没权限,也不是本地玩家。在机器B上,playA与playB
isServer为false,isClent为true,其中playB有权限,是本地玩家,A没权限,也不是本地玩家。A与B上的PlayA的netID相同,A与B上的PlayB的netID也相同,其中netID用来表示他们是同一网络物体在不同的机器上。
  在下面用网络物体来表示带有NetworkIdentity组件的GameObject.
  NetworkConnection:定义一个客户端与服务器的连接,包含当前客户端监视那些服务器上的网络物体,以及封装发送和接收到服务器的消息。
  NetworkClient:主要持有当前NetworkConnection对象与所有NetworkClient列表的静态对象,处理一些默认客户端的消息。
  网络物体上的监视者就是一个或多个NetworkConnection,用来表示一个或多个客户端对这个网络物体保持监视,那么当这个网络物体在服务器上更新后,会自动更新对所有监视者的对应的网络物体。
  NetworkScene:简单来说,1Server与Client需要维护一个网络物体列表,Server可以遍历所有网络物体发送消息等,并且维持Server与Client上的网络物体保持同步,并且客户端记录需要注册的prefab列表.其中NetworkServer与ClientScene都包含一个NetworkScene对象,引用网络物体列表。
  NetworkServer:主要持有一个NetworkScene并且做一些只有在服务器上才能对网络服务做的事,如spawn, destory等。以及维护所有客户端连接。
  ClientScene:主要持有一个静态NetworkScene对象,用于注册网络物体的prefab列表,以及客户端场景上已经有的网络物体列表,处理SyncVar,Rpc,SyncEvent特性等,还有以及ObjectSpawn,objectDestroy,objectHide消息等。
  UNet用时想到的问题与源码的答案& && & 问题1 spawn发生了什么,客户端为什么要注册相应的prefab.
  1 当服务器spawn一个网络物体时,网络物体调用OnStartServer,分配netID.并注册到相应服务器上的的NetworkScene的网络物体列表中,更新如isServer为true等信息。
  2 查找所有客户端连接,查看每个客户端连接是否需要监视这个网络物体,如果为true,那么给这个客户端上一个消息MsgType.ObjectSpawn或是MsgType.ObjectSpawnScene(这种一般是服务场景变换后自动调用),并传递上面的netID.
  3 当客户端接受到ObjectSpawn消息,会在注册的prefab里查找,查找到后Instantiate个网络物体,当接受到ObjectSpawnScene时,会在场景里查找这个网络物体,然后都注册到ClientScene里的NetworkScene的网络物体列表中,并更新netID与服务器的一样。更新如isClent为true等信息。
  我们手动spawn一个物体时,调用的是ObjectSpawn消息,客户端接到这个消息处理得到一个assetID,我们要根据prefabe实例一个新对象,只有客户端注册了相应的prefabe信息才能根据对应的assetID找到prefabe.
  问题2 NetworkIdentity的netID表示什么,那个时候分配。
  当服务器与客户端的netID相同,表示他们是同一物体,相应标示如SyncVar,服务器变了,对应客户端上相同的netID的网络物体,更新成服务器上的数据,Rpc,Commandg 一般也是相同的netID之间调用。
  分配一般发生在服务器spawn一个网络物体时,网络物体调用OnStartServer时发生产生netID。
  在客户端接受相应的ObjectSpawn消息,会把服务器上的对应物体的netID传递过来,产生新的网络物体并赋这个netID。
  问题3 NetworkIdentity的sceneID是什么,在场景里已经有NetworkIdentity组件的物体是如何在客户端与服务器联系的。
  当网络物体并不是spawn产生在服务器与客户端,而是在服务器与客户端场景本身就有时,我们也需要在服务器与客户端之间建立联系,这种物体会有一个sceneID来标示,这种模型一般是服务器场景变换完成后,NetworkServer调用spawnObjects会把这种网络物体与所有客户端同步,当spawn完成后过后,相应客户端会产生一个和服务端相同的netID。
  问题4 服务器场景切换后,各个NetworkIdentity组件的物体如何与客户端联系。
  如下顺序因为有异步操作,并不能确定,如下顺序只是一般可能的顺序。
  1。服务器异步调用场景,发送给所有客户端开始切换场景。MsgType.Scene
  2。客户端接受MsgType.Scene,开始切换场景。
  3。服务器场景完成,会查找所有的网络物体,然后spawn这些网络物体,这样各个网络物体通过相同的netID联系起来。
  4。客户端场景完成后,再次调用OnClientConnect,一般来说,不执行任何操作。
  问题5 客户端为什么要网络物体的权限,它有了权限能做什么。
  一般来说,当spawn某个服务器上的网络物体后,服务器有它的权限,客户端并不能更改这个网络物体,或是说更改这个网络物体相应的属性后并不能同步到服务器和别的客户端上,只是本机上能看到改变。
  那么我如果需要能改变这个网络物体上的状态,并能同步到所有别的客户端上,我们需要拥有这个网络物体的权限,因为这样才能在本机上发送Command命令,才能告诉服务器我改变了状态,服务器也才能告诉所有客户端这个网络物体改变了状态。
  其中本地player在创建时,当前客户端对本地player有权限。客户端上有权限的网络物体上的SyncVar改变后,也并不会能同步到服务器,服务器根本没有注册UpdateVars消息,这种还是需要客户端自己调用Command命令。
  问题6 UNet常见的封装状态同步处理有那些,其中NetworkTransform与NetworkAnimator分别怎样通信,如果是客户端权限的网络物体又是怎么通信的了。
  UNet常见的封装状态同步状态方法有二种。
  一是通过ClientRpc与Command是封装发送消息。客户端与服务端一方调用,然后序列化相应的参数,然后到服务器与客户端反序列化参数执行。
  二是网络内置的序列化与反序列化,序列化服务器的状态,然后客户端反序列化相应的值,如SyncVar通过相应的OnSerialize,OnDeserialize.这种只能同步服务器到客户端。
  这二种本质都是客户端与服务器互相发送MsgType消息,对应的服务器与客户端注册相应消息处理。NetworkAnimator 服务器上的动画改变,会发消息通知所有客户端相应状态改变了,如Rpc。NetworkTransform 服务器通过OnSerialize序列化相应的值,然后客户端反序列化相应的值。
  如果客户端有对应NetworkTransform与NetworkAnimator网络物体的权限。NetworkAnimator 相应客户端提交状态到服务器上,然后分发到所有客户端,相当于调用了Command,并在Command里调用了Rpc方法。NetworkTransform 相应客户端发送消息到服务器上,服务器更新相应位置,方向。然后通过反序列化到所有客户端。
  所以如果客户端有授权,那么NetworkAnimator与NetworkTransform在服务器或是有授权的客户端的状态改变都能更新到所有客户端,注意这二个组件对localPlayerAuthority的处理不同,在NetworkTransform中,localPlayerAuthority为false时,客户端不能更新到所有客户端,在NetworkAnimator中,localPlayerAuthority为true时,服务器不能更新到客户端上。
  其中注意SyncVar特性,就算客户端授权,客户端改变后,也不会同步到别的机器上。
  所以如果我们自己设计类似的网络组件,需要考虑客户端授权的相应处理,就是差不多添加一个Command命令。
  问题7 客户端授权与本地player授权有什么区别。
  一般物体的权限都在服务器上,如果要对网络物体授权给客户端,一般通过SpawnWithClientAuthority实现,这样在相应客户端上的hasAuthority为true,其中相应的playerControllerID为-1。
  而本地player授权localPlayerAuthority,在相应的网络物体上的Local Player Authority勾选上,在对这个网络物体的所有监视客户端上,本地player授权都是true,这种一般用于玩家,或是玩家控制位移的物体,playerControllerID大于等于0。
  所以客户端授权针对是某个客户端,在这个客户端上的这个网络物体的hasAuthority为true,而本地player针对是某个网络物体,在所有客户端上的这个网络物体的localPlayerAuthority都为true.
  问题8 UNet怎么实现迷雾地图
  通过NetworkProximityChecker,这样每桢检测当前网络物体的监视连接,确定那些客户端需要这个网络物体。同样,想实现更复杂的可以自己实现类似。
  问题9 NetworkServer.Destroy做了啥
  必须是网络物体,且最好能在服务器调用,调用时,发给所有的监视Connect,销毁对应网络物体,然后服务器销毁。请看MsgType.ObjectDestroy消息流程.
  需要注意的是在服务器中,Destroy某网络物体,会自动调用NetworkServer.Destroy。代码在NetworkIdentity.OnDestroy.
  问题10 服务器添加角色时做了那些事。
  当客户端连接服务器时,设置自动创建角色后,会自动创建角色。
  1 服务器添加一个player,设定playercontrollerID
  2 设置当前conn的ready为true.然后检测当前的conn是否需要监视服务器上NetworkScene的网络物体列表的各个网络物体,其中客户端上的isspawnFinished表示NetworkScene的网络物体列表是否检测完成。
  3 把服务器的player的spawn下去,设定对应网络物体记录的本地权限客户端为当前客户端,相应的playercontrollerid发送到客户端。
  问题11 NetworkClient与networkServer的active表示什么,那些时候用
  networkServer开始监听后,设定active为true。
  networkClient连接上服务器后,设定为true。
  当有些消息发送,或是Rpc与Command等的调用时,时机可能会在active之前,引发错误。
  问题12 网络的Update做些啥。
  1 服务器更新,处理一些如客户端链接与丢失链接,还有接收消息并找到对应事件处理,以及序列化服务器网络物体要更新的数据。
  2 客户端更新,如上服务器的处理,主要也是相应消息处理。
  3 检查服务器与客户端的场景是否加载完成。
  最后,想象一下,在网络环境下,我们拉开弓箭,生成箭,箭在客户端上缓缓拉开,我们应该如何做?
  首先弓箭要让所有客户端看的到,我们要在服务器上生成,然后spawn分发到相应多个客户端,然后当前客户端还需要当前箭的权限,这样当前用户才能控制这把箭,并把当前用户控制箭产生的新位置同步给所有的客户端。
  其次如果采用Valve的LabRender渲染器,需要在开始服务器时关闭,等到对应的角色加载后,再通过localplayer打开各自对应的valveCamer,不然服务器上的valveCamer可能得不到正确的阴影图。
  如果有分析不对的地方,欢迎大家指出。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:308次
排名:千里之外3007人阅读
Editor私人定制(140)
单人游戏转换为多人&& 孙广东&&
本文档描述将单人游戏转换为使用新的网络系统的多人游戏的步骤。这里描述的过程是简化,对于一个真正的游戏其实需要更高级别版本的实际流程,现在介绍的是不工作就像这的每一场比赛,但它提供了基本配方。1、NetworkManager 安装o 向场景添加一个新的游戏对象并将它重命名为&NetworkManager&。o 为新的游戏对象添加NetworkManager 组件。o 将 NetworkManagerHUD 组件添加到游戏物体。这将为管理网络游戏状态提供默认 UI。2、Player Prefab 安装o 在游戏中Find player的预制体prefab,或者从player对象创建一个预置。o NetworkIdentity 组件添加到player prefab上。o 检查 NetworkIdentity 的 LocalPlayerAuthority box 。o 在player prefab的NetworkManager 组件上为 “Spawn Info” 设置 playerPrefabo 从现场删除player 对象实例,如果它存在于现场3、Player Movemento 将 NetworkTransform 组件添加到 player prefabo 更新输入和控制脚本来遵守 isLocalPlayero 修复camera 使用衍生出的player 和 isLocalPlayer例如,此脚本只处理local player输入:using UnityE
using UnityEngine.N
public class Controls : NetworkBehaviour
void Update()
if (!isLocalPlayer)
// exit from update if this is not the local player
// handle player input for movement
4、Basic Player Game Stateo 使脚本包含重要数据到NetworkBehaviours&, 而不是 MonoBehaviours o 使重要成员变量到 SyncVars5、Networked Actionso 使脚本执行NetworkBehaviours重要操作成而不是 MonoBehaviours o Update函数执行player操作的重要命令6、Non-Player Objects修改非玩家prefabs,像敌人等:o 添加 NetworkIdentify 组件o 添加 NetworkTransform 组件o NetworkManager注册 spawnable 预置体o 更新脚本与游戏状态和操作7、Spawnerso 可能更改的spawner 脚本要继承自 NetworkBehaviourso 修改spawners 只运行在服务器上,使用 isServer 属性或 OnStartServer() 函数o 为创建对象调用 NetworkServer.Spawn()8、Player的产生的位置o 添加一个新的游戏对象,并将它放在玩家的应该开始的位置o 新的游戏对象添加 NetworkStartPosition 组件9、Lobbyo Create Lobby Scene创建大厅现场o Import multiplayer-lobby package导入多人游戏大厅包o 添加 GuiLobbyManager 预置到场景o Configure the manager配置 管理器&&&& & oScenes&&&&& o Prefabs&&&&& o spawners
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:714670次
积分:10567
积分:10567
排名:第1222名
原创:252篇
转载:15篇
译文:32篇
评论:184条
阅读:11837
文章:13篇
阅读:59849
阅读:40443
文章:25篇
阅读:117012
爱科技、爱游戏、有梦想、一起!
(2)(2)(4)(5)(6)(2)(10)(7)(5)(5)(3)(7)(2)(5)(3)(4)(7)(16)(26)(12)(10)(22)(28)(4)(9)(2)(6)(10)(16)(13)(2)(8)(3)(2)(5)(3)(11)(14)扫一扫,访问微社区
后使用快捷导航没有帐号?
签到成功!您今天第{todayrank}个签到,签到排名竞争激烈,记得每天都来签到哦!已连续签到:{constant}天,累计签到:{days}天
当前位置: &
查看: 7749|回复: 176
Unity5网络教程之UNET(一):HLAPI简介
7排名<font color="#FF昨日变化1主题帖子积分
在线时间399 小时
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
才可以下载或查看,没有帐号?
本帖最后由 小刺刺 于
11:40 编辑
在本系列教程中,我们将使用的网络高级API(HLAPI)来构建一个小型的多人网络案例。即使我们的例子很简单,但也会涵盖以下关键概念,这应该可以帮助大家使用HLAPI构建大型游戏项目。在第一部分,我们将使用NetworkBehaviours,SyncVars和Commands来介绍客户端和服务器之间的通信。在第二部分,我们将实现客户端预测和服务器同步。在第三部分,我们将快速看看服务通道质量。
希望通过尽量保持项目精简,可以很容易的提炼并理解教程演示的网络原理,从而可以将这些概念应用到你自己的游戏中。
需要熟悉Unity基本概念。具体来说就是知道MonoBehaviour是什么,以及与GameObject的关系,并且知道里面诸如Awake、Start、Update之类的事件函数是如何及何时被调用的。不了解Unity Networking也没关系。
我们的实现是基于Gabriel Gambetta在他的系列文章Fast-Paced Multiplayer(快节奏多人游戏)中所描述的架构。引用了他系列文章的第二篇来理解如何在项目中实现客户端预测和服务器同步。
应该说这篇文章基本来自Unity文档《》的附加说明。想尽快上手HLAPI的开发者可以看看这个文档。也可将其作为HLAPI的使用指南。
项目文件可以在文末下载。项目大部分由自定义的MonoBehaviour驱动,并且它带上空白行也只有115行。建议下载示例工程,以查看所有代码并实际运行,再学习本文就可以更好的理解整个工作原理。
开工我们先创建一个Cube,可以用方向键控制它从一个网格位置移动到另一个。
用结构体存储Cube的当前位置:
[C#] 纯文本查看 复制代码struct CubeState {
在Awake函数里设置Cube的初始位置:
[C#] 纯文本查看 复制代码void Awake () {
InitState();
void InitState () {
state = new CubeState {
大部分工作在Update函数中去做,这里简单检测方向键按下并做出相应动作:
[C#] 纯文本查看 复制代码void Update () {
KeyCode[] arrowKeys = {KeyCode.UpArrow, KeyCode.DownArrow, KeyCode.RightArrow, KeyCode.LeftArrow};
foreach (KeyCode arrowKey in arrowKeys) {
if (!Input.GetKeyDown(arrowKey))
state = Move(state, arrowKey);
SyncState();
void SyncState () {
transform.position = new Vector2(state.x, state.y);
如果方向键真的被按下,就用Move函数计算Cube的新网格位置,这个函数将Cube的前一个网格位置和方向键作为参数,并返回Cube的新网格位置:
[C#] 纯文本查看 复制代码CubeState Move(CubeState previous, KeyCode arrowKey) {
int dx = 0;
int dy = 0;
switch (arrowKey) {
case KeyCode.UpArrow:
case KeyCode.DownArrow:
case KeyCode.RightArrow:
case KeyCode.LeftArrow:
return new CubeState {
x = dx + previous.x,
y = dy + previous.y
现在只是简单的使用了Unity的非多人游戏的基础特性。希望大家都比较熟悉。否则建议大家先熟悉Unity基础,然后再回到本文学习如何使用用Unity做多人游戏。下面来添加多玩家功能。
总览观察网络模拟工作方式的一种办法是,将场景作为被多位玩家共享的场景。在这种设置下,每个玩家被分配一个独有的GameOject。在本例子中,我们将为各连接上的玩家分配一个Cube。接下来就要试着解决以下:
1.怎样在玩家间建立链接?
2.怎样将多个Cube实例化给在线玩家?
3.服务器如何保持所有在线玩家的内容一致?
4.玩家如何告知服务器Cube要移动了?
HLAPI遵循CS架构,这意味着机器间不能直接相连,而是将一台机器作为服务器,所以其他机器作为客户端连接到服务器。服务器同时也能作为客户端使用,所以不需要有一个专用服务器(尽管这也可行)。我们将建立工程,它可能运行在单服务器模式下或者同时作为客户端和服务端(也被称作主机模式)。
记住,在Unity中,功能是由GameObject结合它带有的Component决定的。我们遵循这点来实现服务器或者客户端。
1.创建一个空的GameObject。命名为“NetworkManger”。
2.添加NetworkManager 组件。这个组件提供了一个简单控制HLAPI的方式。
3.添加NetworkManagerHUD 组件。这个组件提供了一个基本的控制NetworkManger的UI。
搞定了!用HLAPI很容易将项目作为服务器启动或者作为客户端链接到服务器。
为客户端分配玩家游戏物体
目前为止,尽管连接已经建立,但还没有内容。当一个玩家连接时,我们想要实例化一个Cube并让玩家可以控制这个Cube。使用Player Object来实现:
1.首先,为已经存在的Cube游戏对象并为它添加NetworkIdentity 组件。这会告诉HLAPI要处理这个游戏物体的网络方面。
2.将这个游戏对象转换为预制件。
3.将这个预制件赋给NetworkManger的“Player Prefab”字段。
4.如果Cube还留在场景中,删掉它。一个新玩家链接时会自动创建一个Cube实例。因为Cube带有NetworkIdentity组件,HLAPI也会知道这是一个网络游戏对象,这将使得同样的Cube会被实例化到所有链接的客户端。
跨机器同步MonoBehavior
如果之前没有做过网络游戏,你可能认为给一个GameObject添加NetworkIdentity组件不会自动同步到网络中的所有其它客户端。在我看来,不自动同步真的是一件好事,因为不同游戏有不同的需求,并且控制同步和不允许的内容可以让游戏性能更好,某些情况下甚至可以让游戏设计更灵活。
用HLAPI在网络上同步MonoBehaviour的数据也很简单:
1.子类NetworkBehaviour代替了MonoBehaviour。NetworkBehaviour是基于MonoBehaviour并添加了可以在客户端和服务端传输数据的功能。做一点很简单的改变即可,将:
[C#] 纯文本查看 复制代码public class CubePlayer : MonoBehaviour
[C#] 纯文本查看 复制代码public class CubePlayer : NetworkBehaviour
通过使用NetworkBehaviour,就可以在代码里使用HLAPI的数据传输功能。
2.用SyncVar 属性将成员变量标记为要被同步的。这里我们只需要将:
[C#] 纯文本查看 复制代码CubeS
[C#] 纯文本查看 复制代码[SyncVar] CubeS
通过标记变量为SyncVar,这个变量值在服务器上的任何更新都会广播到所有已链接的客户端。只要确保SyncVars 的所有改变是由服务端产生即可。
到这里,如果运行工程,就会看到当按下方向键,屏幕上的所有的Cube都响应输入,这不是我们希望的,只要自己的Cube能响应输入即可。为了更正这点,只需在Update函数中做一个细微的调整,如下:
[C#] 纯文本查看 复制代码void Update () {
if (isLocalPlayer) {
// handle input here...
SyncState();
isLocalPlayer变量告诉我们处理的玩家物体是否是自己的。如果不是,将忽略任何输入;如果是,就移动cube。
“跨机器同步MonoBehaviour”部分的最后一句话留下了十分重要的线索,下一步应该做什么。为了让SyncVars 生效,它们应该从服务器上更新。但现在的代码不是如此:
1.只要有方向键被按下,每个客户端直接更新被标记为SyncVar的变量。
2.只有主机的更新传播到所有链接的客户端,实际上忽略了任何其它人的更新。
记住SyncVar只能被服务器修改,所以我们要做的是:
1.当客户端的方向键按下,客户端应该告诉服务器方向键被按下了。
2.反过来,服务器应该根据收到的输入更新SyncVar。
3.因为SyncVar由服务器更新,所有的变化都被正确的传递到所有链接的客户端上。
HLAPI给我们提供了一个从客户端调用服务器函数的方法,使用Commands。可将已经存在的函数转换为Commands,通过如下方式标记它们(与将变量标记为SyncVar类似):
1.添加Command属性。
2.在函数名前添加Cmd前缀。
例如,这个函数:
[C#] 纯文本查看 复制代码void MoveOnServer (KeyCode arrowKey) {
state = Move(state, arrowKey);
这样就能将函数变成一个Command:
[C#] 纯文本查看 复制代码[Command] void CmdMoveOnServer (KeyCode arrowKey) { /* ... */ }
一旦有了Command,就能像调用其它函数一样调用这个函数,但是因为它被标记为Command,所以在客户端调用函数里的代码将运行在服务器上。回到例子,只需将Update函数里的如下行:
[C#] 纯文本查看 复制代码state = Move(state, arrowKey);
[C#] 纯文本查看 复制代码CmdMoveOnServer(arrowKey);
只需做些简单的改变,就能在服务器上执行函数了,现在SyncVar现在被正确更新了。
注意,Command只能被你自己的Player Object调用,这防止了一个客户端接管其它客户端的控制。在服务器端确保了是谁在调用函数,这将帮助我们确保多玩家网络游戏的安全。
仅服务器调用的函数
[Server] void InitState () { /* ... */ }
在教程结束前,再看一下Awake 函数,只有一行代码就是调用InitState。为了让Demo理想运行,需要确保这个初始化只在服务器上运行而不能在客户端。方式是标记InitState作为一个仅服务端调用的函数。还好用HLAPI很容易做到这点。我们要做的就是标记函数为Server属性,如下:
[C#] 纯文本查看 复制代码[Server] void InitState () { /* ... */ }
如果在服务器/主机下调用InitState,它就能正常运行。否则,调用会被忽略。
运行Demo,你可能会注意到当试着控制Cube的时候,按下按键和到盒子在屏幕上移动之间有延迟。因为从客户端发送按键信息到服务器要花费一些时间,并且从服务端发送Cube的状态信息还要花费更多时间。
还好有一个隐藏延迟的方法,我们将在本系列的第二篇中谈到。
最后,附上工程:
游客,如果您要查看本帖隐藏内容请
扫描下方二维码关注“”官方微信~每日都有精选干货与你分享呦~
原文链接:
原文作者:Christian Arellano
本文由蛮牛译馆倾情奉献,除 合作社区 及 合作媒体 外,禁止转载。
.0隐藏物体;unity5 demo 下载;unity5 隐藏物体;unity5.4 demo 下载
每日推荐:
2139/150排名<font color="#FF昨日变化14主题帖子积分
初来乍到, 积分 139, 距离下一级还需 11 积分
初来乍到, 积分 139, 距离下一级还需 11 积分
在线时间58 小时
感谢分享& && && && &
每日推荐:
61495/1500排名<font color="#FF昨日变化主题帖子积分
蛮牛粉丝, 积分 1495, 距离下一级还需 5 积分
蛮牛粉丝, 积分 1495, 距离下一级还需 5 积分
蛮牛币3018
在线时间393 小时
终于有UNET的教程了,希望简单点
每日推荐:
4437/500排名<font color="#FF昨日变化1主题帖子积分
四处流浪, 积分 437, 距离下一级还需 63 积分
四处流浪, 积分 437, 距离下一级还需 63 积分
蛮牛币1073
在线时间138 小时
看看~~~~~~~~~~~~~~~~~~~~~~··
每日推荐:
61010/1500排名<font color="#FF昨日变化13主题帖子积分
蛮牛粉丝, 积分 1010, 距离下一级还需 490 积分
蛮牛粉丝, 积分 1010, 距离下一级还需 490 积分
在线时间528 小时
学习了,楼主辛苦了~~赞个
每日推荐:
61276/1500排名<font color="#FF昨日变化主题帖子积分
蛮牛粉丝, 积分 1276, 距离下一级还需 224 积分
蛮牛粉丝, 积分 1276, 距离下一级还需 224 积分
蛮牛币2452
在线时间354 小时
感谢分享。。。。。。。。。。。。
每日推荐:
4310/500排名<font color="#FF昨日变化5主题帖子积分
四处流浪, 积分 310, 距离下一级还需 190 积分
四处流浪, 积分 310, 距离下一级还需 190 积分
在线时间91 小时
太好了,感谢分享干货
每日推荐:
61001/1500排名<font color="#FF昨日变化1主题帖子积分
蛮牛粉丝, 积分 1001, 距离下一级还需 499 积分
蛮牛粉丝, 积分 1001, 距离下一级还需 499 积分
在线时间265 小时
Unity5网络教程之UNET(一):HLAPI简介
每日推荐:
71501/5000排名<font color="#FF昨日变化2主题帖子积分
日久生情, 积分 1501, 距离下一级还需 3499 积分
日久生情, 积分 1501, 距离下一级还需 3499 积分
蛮牛币4094
在线时间401 小时
还好有一个隐藏延迟的方法,我们将在本系列的第二篇中谈到
每日推荐:
132/50排名<font color="#FF昨日变化29主题帖子积分
注册看看, 积分 32, 距离下一级还需 18 积分
注册看看, 积分 32, 距离下一级还需 18 积分
在线时间16 小时
每日推荐:
5692/1000排名<font color="#FF昨日变化1主题帖子积分
熟悉之中, 积分 692, 距离下一级还需 308 积分
熟悉之中, 积分 692, 距离下一级还需 308 积分
蛮牛币1792
在线时间189 小时
学到很多东东,谢谢& && && && && && && && && && && && && && && && && && && &&&
每日推荐:
72497/5000排名<font color="#FF昨日变化主题帖子积分
日久生情, 积分 2497, 距离下一级还需 2503 积分
日久生情, 积分 2497, 距离下一级还需 2503 积分
蛮牛币7416
在线时间720 小时
学习一下网络
每日推荐:
13/50主题帖子积分
注册看看, 积分 3, 距离下一级还需 47 积分
注册看看, 积分 3, 距离下一级还需 47 积分
在线时间1 小时
看看 应该不错 学习一下
每日推荐:
3180/300排名<font color="#FF昨日变化9主题帖子积分
偶尔光临, 积分 180, 距离下一级还需 120 积分
偶尔光临, 积分 180, 距离下一级还需 120 积分
在线时间61 小时
支持支持支持~~~~~~~~~~~~~
每日推荐:
73062/5000排名85昨日变化主题帖子积分
日久生情, 积分 3062, 距离下一级还需 1938 积分
日久生情, 积分 3062, 距离下一级还需 1938 积分
蛮牛币7132
在线时间1129 小时
感谢粉下锅啊啊啊啊啊啊啊实打实发多少大神大神
每日推荐:
经过游戏蛮牛认证的蛮牛小翻译
社区QQ达人
使用QQ帐号登录论坛的用户
购买游戏蛮牛书籍

我要回帖

更多关于 unity unet教程 的文章

 

随机推荐