Unity中的网络编程

unity如何制作局域网游戏 unity联机游戏 unity局域网连接 阅读详情

转自:http://blog.youkuaiyun.com/zhou_xw6511/article/details/8479485


首先要说明的是,Unity本身的网络功能并不适合做MMO类型的游戏。如果要使用Unity作为MMO游戏的客户端,一般来说都是在C#中通过socket建立自定义的网络通信来实现。Unity本身的网络功能是为多人游戏设计的,这种游戏模式一般来说就是一个玩家建立游戏(这个玩家既是server,又是client),其他玩家连接进来。从带宽考虑一般同时支持的玩家数量小于64个(这个也不一定,要看游戏本身的设计)。这些玩家一般都在一个局域网内互联,但是如果使用MasterServer进行配对,也可以在Internet上相互连接。很多所谓的单机并支持多人连线的游戏基本上都是用这样的网络模式。Unity本身的网络功能是可以跨平台的,可以运行于PC,IOS,Android,并且支持不同平台的客户端通信。

网络协议

Unity网络协议本身是一个比较高层的网络协议,他并不是独立存在的,而是与引擎的游戏对象结合在一起,为游戏提供网络功能支持。要说明Unity的网络协议,就先要说明一下在网络模式下游戏对象的管理。

网络游戏对象管理

在Unity网络模式下,创建一个游戏对象实例,是通过Network.Instantiate()函数来实现的。这个函数与Object.Instantiate()类似,会在本地创建一个游戏对象实例,并且还会在所有互联的主机上也同时创建同样的游戏对象实例,这些游戏对象具有相同的NetworkView ID。每个被创建出来的游戏对象都使用NetworkView.isMine来标识自己的身份。如果isMine为true,就表示此游戏对象是本机创建的;false则表示是其他主机创建,并同步到本机的。游戏对象的isMine身份与网络底层的server和client身份没有任何关系,在server和client上都可以有任何身份的游戏对象存在,这主要取决于游戏对象是谁创建的。如果要销毁游戏对象,应该调用Network.Destroy()来代替Object.Destroy(),他会在所有主机上销毁这个对象。

基于游戏对象的网络协议

在Unity中不存在单纯的“发送给服务器”或“发送给客户端的”网络消息,Unity的网络协议是基于一个具体的游戏对象的通信协议,这就意味着所有的通信上下文都与一个具体的游戏对象有关。一旦在网络环境下创建了游戏对象,这些在各个主机上被创建的游戏对象之间就已经建立好了通信关系,任何一个主机上的游戏对象都可以与其他主机上的“自己”进行通信。不同的游戏对象之间的通信是独立的,就好像每个游戏对象都有一个独立的通信管道。

游戏对象之间的通信在形式上分为两种:

状态同步

游戏对象中经常发生变化,并且可以被描述成对象属性的数据。状态同步的方向只能是isMine到非isMine。比如一个玩家角色对象hp属性,如果需要其他玩家能够看到,就可以使用状态同步来完成。当isMine的玩家角色的hp变化后,会自动更新这个属性给其他的主机上的同一个玩家角色对象。状态同步还支持保证和非保证模式。

RPC

在其他主机的相同游戏对象上执行一个远程函数调用。RPC一般用来通过网络通知一次性的游戏事件,比如”游戏对象A受到了30点伤害“等等。RPC的传输方向非常自由,可以在一个主机向任何其他主机,包括自己,发送RPC调用。


网络游戏对象管理+状态同步+RPC组成了Unity的网络协议,所有需要实现的多人游戏的网络功能都是构建在这套Unity网络协议的基础之上的。


使用Unity构建多人游戏

传递游戏对象引用

在构建多人游戏过程中,除了需要通过网络传递一些基本数据类型的数据(int, string...),有时候还需要传递一个游戏对象的引用。比如游戏对象A通过RPC通知给其他主机他消灭了游戏对象B,这里B就是游戏对象的引用。类似的需要还有很多,那么我们如何传递这个引用呢?这就需要NetworkView.viewID了。NetworkView.viewID是一个NetworkViewID类型的对象,RPC本身支持传输这种数据类型。在发送方只要将B的NetworkView.viewID当作RPC的参数传递给接收方,接收方再通过NetworkView.Find()在本地将viewID转换成对应的游戏对象引用就可以了。

全局对象

在单机游戏中,场景中一般会创建一个游戏的全局对象,来处理整体的游戏状态。比如关卡的完成情况,全局的事件处理等等。在多人游戏中,同样也需要这样的功能。一般来说,这个全局对象可以在server端创建成网络游戏对象,并复制给其他的client。这个全局对象一般用来处理以下功能:

  • 新连接的处理:当一个client连接到server后,全局对象会被自动创建到该client。client可以使用基于这个全局对象的一个RPC,当作第一条发送给服务器的消息,这个消息一般带有自己的身份和游戏信息。server处理这个RPC来实现游戏层面的玩家登录。
  • 同步场景切换:当游戏需要所有玩家同时切换场景时,需要全局对象进行通知和同步。
  • 游戏状态管理和同步:全局游戏对象一般在server端运行游戏逻辑,并将需要client知道的游戏状态和游戏事件通知给所有的client。

融合单人游戏

多人游戏一般带有单人模式,而且他们很多游戏逻辑是相同的。在编写游戏逻辑代码时,除了必须的网络功能代码外,应该尽量掩盖单人与多人游戏的区别,使代码更好理解和维护。我们可以把单人游戏看成是只有一个本地客户端的多人游戏,并且屏蔽掉网络功能而已。

使用NetworkViewWrapper代替直接使用NetworkView,使isMine在单机模式下也有效,并且屏蔽掉单机模式的RPC功能。


NetworkViewWrapper.cs
[csharp]  view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. /** 包装NetworkView,使之能够兼容非网络模式. */  
  5. [RequireComponent(typeof(NetworkView))]  
  6. public class NetworkViewWrapper : MonoBehaviour  
  7. {  
  8.     public int group  
  9.     {  
  10.         get { return networkView.group; }  
  11.         set { networkView.group = value; }  
  12.     }  
  13.     public bool isMine   
  14.     {   
  15.         get   
  16.         {   
  17.             if(Network.peerType == NetworkPeerType.Disconnected)  
  18.                 return true;  
  19.             return networkView.isMine;   
  20.         }   
  21.     }  
  22.     public Component observed   
  23.     {  
  24.         get { return networkView.observed; }  
  25.         set { networkView.observed = value; }  
  26.     }  
  27.     public NetworkPlayer owner  
  28.     {   
  29.         get { return networkView.owner; }   
  30.     }  
  31.     public NetworkStateSynchronization stateSynchronization  
  32.     {  
  33.         get { return networkView.stateSynchronization; }  
  34.         set { networkView.stateSynchronization = value; }  
  35.     }  
  36.     public NetworkViewID viewID  
  37.     {  
  38.         get { return networkView.viewID; }  
  39.         set { networkView.viewID = value; }  
  40.     }  
  41.   
  42.     public static NetworkViewWrapper Find(NetworkViewID viewID)  
  43.     {  
  44.         NetworkView nvw = NetworkView.Find(viewID);  
  45.         return (nvw == null) ? null : nvw.GetComponent<NetworkViewWrapper>();  
  46.     }  
  47.     public void RPC(string name, NetworkPlayer target, params object[] args)  
  48.     {  
  49.         if (Network.peerType == NetworkPeerType.Disconnected)  
  50.             return;  
  51.         networkView.RPC(name, target, args);  
  52.     }  
  53.     public void RPC(string name, RPCMode mode, params object[] args)  
  54.     {  
  55.         if (Network.peerType == NetworkPeerType.Disconnected)  
  56.             return;  
  57.         networkView.RPC(name, mode, args);  
  58.     }  
  59. }  
[csharp]  view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. /** 包装NetworkView,使之能够兼容非网络模式. */  
  5. [RequireComponent(typeof(NetworkView))]  
  6. public class NetworkViewWrapper : MonoBehaviour  
  7. {  
  8.     public int group  
  9.     {  
  10.         get { return networkView.group; }  
  11.         set { networkView.group = value; }  
  12.     }  
  13.     public bool isMine   
  14.     {   
  15.         get   
  16.         {   
  17.             if(Network.peerType == NetworkPeerType.Disconnected)  
  18.                 return true;  
  19.             return networkView.isMine;   
  20.         }   
  21.     }  
  22.     public Component observed   
  23.     {  
  24.         get { return networkView.observed; }  
  25.         set { networkView.observed = value; }  
  26.     }  
  27.     public NetworkPlayer owner  
  28.     {   
  29.         get { return networkView.owner; }   
  30.     }  
  31.     public NetworkStateSynchronization stateSynchronization  
  32.     {  
  33.         get { return networkView.stateSynchronization; }  
  34.         set { networkView.stateSynchronization = value; }  
  35.     }  
  36.     public NetworkViewID viewID  
  37.     {  
  38.         get { return networkView.viewID; }  
  39.         set { networkView.viewID = value; }  
  40.     }  
  41.   
  42.     public static NetworkViewWrapper Find(NetworkViewID viewID)  
  43.     {  
  44.         NetworkView nvw = NetworkView.Find(viewID);  
  45.         return (nvw == null) ? null : nvw.GetComponent<NetworkViewWrapper>();  
  46.     }  
  47.     public void RPC(string name, NetworkPlayer target, params object[] args)  
  48.     {  
  49.         if (Network.peerType == NetworkPeerType.Disconnected)  
  50.             return;  
  51.         networkView.RPC(name, target, args);  
  52.     }  
  53.     public void RPC(string name, RPCMode mode, params object[] args)  
  54.     {  
  55.         if (Network.peerType == NetworkPeerType.Disconnected)  
  56.             return;  
  57.         networkView.RPC(name, mode, args);  
  58.     }  
  59. }  

使用NetObject封装对象的创建和销毁
NetObject.cs
[csharp]  view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public static class NetObject  
  5. {  
  6.     public static Object instantiate(Object prefab, Vector3 position, Quaternion rotation)  
  7.     {  
  8.         if (Network.peerType == NetworkPeerType.Disconnected)  
  9.             return Object.Instantiate(prefab, position, rotation);  
  10.         else  
  11.             return Network.Instantiate(prefab, position, rotation, 0);  
  12.     }  
  13.     public static void destroy(GameObject gameObject)  
  14.     {  
  15.         if (Network.peerType == NetworkPeerType.Disconnected)  
  16.             Object.Destroy(gameObject);  
  17.         else  
  18.             Network.Destroy(gameObject);  
  19.     }  
  20. }  

Unity+ET6.0网络框架的网络开发基础理论 网络编程理论基础 文章目录网络编程理论基础主机间通信概述Socket通信模型游戏服务器架构的演变过程用户登录逻辑详解ET6.0框架下登录源码解释 主机间通信概述 ip地址和端口号 ​ 生活中任何通信方式的前提,都必须知晓对方的一些标志性信息,进而唯一地确定目标进行通信。例如寄快递时的地址,打电话时的手机号等等。主机间的通信也需要一些标志性信息用以唯一的确定通信的双方,这些标志信息即为ip地址和端口号。 ​ 主机间通信的本质,其实是两台主机中程序的通信,例如主机A的微信应用发送一条消息给主机B中的微信应用, 阅读详情

相关推荐

Unity Socket网络编程(TCP)开发步骤

服务器:第一步:创建一个Socket对象1、Socket 对象名 = IPAddress.Parse(寻找地址,套接字类型,协议方式);第二步:绑定监听消息IP和端口号1、 IPAddress ip = IPAddress.Parse("ip地址");      EndPoint endPoint = new IPEndPoint(ip,端口号);2、socket对象.Bind(endPoint)...

qq_35405938的博客 936

Unity客户端和服务器通信【Unity网络编程(四)】

实现Unity客户端与服务器的通信,包括GET的登录和POST方法的数据发送,介绍了请求的发送过程和区别,并且演示了一下基本的案例

cycler_725的博客 4518

Unity:Unity网络编程基础

Unity网络API是Unity引擎中用于实现多人在线游戏和网络通信功能的一套工具。它提供了多种网络模式,包括客户端/服务器模式(C/S模式)和对等模式(P2P模式),以及一系列组件和脚本来帮助开发者构建网络应用。Unity网络API的核心组件包括等,这些组件简化了网络同步和通信的复杂性。在Unity中构建多人游戏,我们通常会使用Unity的内置网络系统或第三方网络库如Photon、Mirror等。本案例将使用Unity的内置网络系统,通过组件和等脚本来实现一个简单的多人游戏。

kkchenjj的博客 1214

Unity 网络编程入门

参考:《Unity3D网络游戏实战》

qq_42194127的博客 1339

Unity引擎开发:Unity基础入门_Unity网络编程基础

本节介绍了 Unity 中网络编程的基础知识,包括网络通信的基本概念、Unity Multiplayer 和 Mirror 的使用方法,以及如何实现简单的多人游戏功能。我们还讨论了一些常见的网络编程问题及其解决方案,并提供了一些优化技巧。通过这些知识和技巧,你可以在 Unity 中实现高效、稳定的多人游戏网络通信。

chenlz2007的博客 1508

Unity引擎开发:Unity基础入门_Unity网络编程基础v1

在网络编程中,网络架构是指网络系统中各个组件的组织方式和它们之间的交互模式。常见的网络架构有客户端-服务器(Client-Server)模型和对等网络(Peer-to-Peer)模型。除了使用Cmd和Rpc方法,Unity 还支持自定义消息传递。自定义消息可以用来传递特定的数据和指令。定义消息类型在的列表中定义消息类型。发送自定义消息使用方法发送自定义消息。接收自定义消息在服务器上注册消息处理回调函数。

chenlz2007的博客 1170

Unity网络编程(1)多线程

目录:1.网络编程基础认识2.线程。

xxxxx666666的博客 3389

Unity:Unity网络编程基础_2024-07-12_21-14-01.Tex

Unity网络API是Unity引擎中用于实现多人在线游戏和网络通信功能的一套工具。它提供了多种网络模式,包括客户端/服务器模式(C/S模式)和对等模式(P2P模式),以及一系列组件和脚本来帮助开发者构建网络应用。Unity网络API的核心组件包括等,这些组件简化了网络同步和通信的复杂性。在Unity中构建多人游戏,我们通常会使用Unity的内置网络系统或第三方网络库如Photon、Mirror等。本案例将使用Unity的内置网络系统,通过组件和等脚本来实现一个简单的多人游戏。

675

Unity网络编程指南

网络编程指南

2302_76776557的博客 1564

Unity套接字网络编程实战指南

网络编程允许游戏或应用程序通过互联网与其他设备进行交互。在Unity中,套接字(Socket)是实现网络通信的基本构件,无论是连接到服务器还是让其他设备连接到本地主机。套接字是一种允许程序在不同设备间发送和接收数据的网络通信端点。在Unity中,通过套接字可以进行数据的发送和接收,无论是文本信息还是二进制数据。在互联网的传输层中,两种广泛使用的协议是传输控制协议(TCP)和用户数据报协议(UDP)。

weixin_35728286的博客 936

windows10 + wsl2安装docker

一、安装wsl https://docs.microsoft.com/zh-cn/windows/wsl/install-win10 1.1以管理员身份运行powershell 1.2执行如下命令 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart 1.3重启电脑 1.4 重启电脑后,如果需要安装wsl2, 则安装官方文档继续后续操作,因我...

happytree001的博客 1568

unity网络编程

Server.js: var connectPort : int = 2224; function OnGUI () { if (Network.peerType == NetworkPeerType.Disconnected) { GUILayout.Label("Connection status: Disconnected"); co

nate的专栏 3868

PFC中pb模型实战:从胶结参数设置到破坏模拟全流程解析

本文详细解析了PFC软件中平行胶结模型(PB模型)的实战应用全流程。从胶结参数(pb_kn, pb_ks, pb_ten等)的物理意义与精准赋值入手,深入探讨了模型构建、胶结施加以避免初始损伤的技巧,并系统介绍了破坏过程的监测、阈值判定方法以及高级可视化与常见问题诊断。旨在帮助岩土工程与颗粒材料研究者掌握从参数调试到破坏模拟的核心操作,提升数值模拟的准确性与效率。

php55的博客 1075

【Unity】Socket网络编程

知识点: Tcp/Ip 四层模型

wangpuqing1997的博客 553

鸿蒙OS开机动画背后的秘密:从代码到视觉的完整解析(附源码分析)

本文深入解析了鸿蒙OS开机动画的系统级实现原理。从bootanimation服务的启动配置、与Render Service的协同,到基于VSync信号的帧率同步与绘制流水线,结合OpenHarmony源码进行了逐行解读。文章揭示了其事件驱动的优雅退出机制,并探讨了视频支持、多屏适配等高级特性与定制化可能,为开发者理解鸿蒙图形子系统提供了硬核技术视角。

sony5的博客 971

阿里云百炼平台创建智能体-上传文档

阿里云百炼智能体-上传文档文件

weixin_43930851的博客 1356

Unity Socket网络编程(TCP)

开发工具:Visual Studio、Unity 开发语言:C# 服务端(Server): using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System...

U3D开发 499

基于一维卷积神经网络对机械振动信号进行分类并加以预测

基于一维卷积神经网络对机械振动信号进行分类并加以预测 *使用一维卷积神经网络训练振动信号进行二分类 2020年7月16日,一学期没等到开学,然而又放假了。 总览优快云中大多数卷积神经网络都是对二维图片进行分类的,而图片也都是常见的猫狗分类,minst手写数字分类。一维卷积神经网络的使用非常少见,有也是IDMB情感分类,和鸢尾花分类的。 作者研究生就读于河北一所双飞,全国排名270多,哈哈哈,不吹不黑。 在网上翻来翻去找不到一篇可以利用的代码去研究我的机械故障诊断,后来在无奈下到某宝搜寻到一段代码,可以利用

qq_45714906的博客 1万+

unity网络编程学习

前言 最近在学习unity自身封装的网络功能,在游戏物体上挂上Network组件,使其成为网络中的一份子,就像这里所说的,Unity网络协议本身是一个比较高层的网络协议,他并不是独立存在的,而是与引擎的游戏对象结合在一起,所以在Unity中不存在单纯的“发送给服务器”或“发送给客户端的”网络消息,不同的游戏对象之间的通信是独立的,就好像每个游戏对象都有一个独立的通信管道。 在游戏中,对

GJQI12的专栏 734

Altium Designer应用技巧13: 四层板的拼版方法

本文介绍在Altium Designer中,进行4层板的拼版方法。Altium Designer有多种拼版方法,本文选择最直观的复制、删帖方法来完成,步骤如下: 1、看一下原始文件,如下图所示,我们要对该板进行拼版操作。 2、通过菜单“报告”-“板子信息”得到板子大小,在这里一般切换为mm比较好操作,我们可以使用快捷键"q"。 3、如果是水平拼版,我们需要关心水平长度;如果是垂直拼版...

snmplink的博客 1万+

Python在Genesis2000 CAM软件中的编程应用

Genesis2000是一款功能强大的计算机辅助制造(CAM)软件,它提供了广泛的功能和工具,用于帮助制造商进行CAD(计算机辅助设计)到CAM的转换。在Genesis2000中,我们可以利用Python的灵活性和功能来扩展软件的自定义能力,并通过编写脚本来自动化各种制造任务。例如,假设我们需要在Genesis2000中添加一个新的操作,用于自动计算零部件的重量。我们可以编写一个Python脚本,通过遍历模型的几何数据并应用相关的计算公式,来实现这个功能。

PixelEnigma的博客 2423

unity RPC网络传输以及网络编程之TCP&UDP的区别

unity 自带的network能满足一般的传输要求了,分两类,远程调用(RPC)和状态同步,其中状态同步适合做位置、方向之类的同步,RPC适合调用方法或提交数据。 要使用RPC 首先服务器端代码和客户端代码中所有的方法都必须一样,没有研究是否可以是方法名相同内容不同的情况。即使不用也要有! 把用于RPC的方法上面写上[RPC] 例如 [RPC] void ReceiveMessage(strin...

Wmayy_123的博客 1627

【Reality Capture 】01:Reality Capture1.5中文版安装教程(附安装包下载)

本文详细介绍了Reality Capture 1.5中文版的安装步骤。首先,下载并解压Reality Capture v1.4.0汉化版安装包,运行EpicInstaller并更改安装路径。接着,启动Epic Games Launcher,登录或注册账号后下载并安装软件。安装完成后,进入主界面并设置中文语言。此外,还提供了中文补丁的拷贝方法,将ui.xml和RealityCapture_CHS.exe文件分别放置到指定目录,并运行RealityCapture_CHS.exe以完成汉化。最后,文章提供了Rea

智慧空间实验室 1749

Unity之网络编程

Unity之光照烘培系统 本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: 光照烘培系统 光照数据的动态加载 光照贴图 动态加载技术 定义列表 Markdown Extra 定义列表语法: 项目1 项目2 定义 A 定义 B 项目3 定义 C 定义 D 定义D内容 代码块 代码块语法遵循标准m...

码农 1081

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

上一篇: unity3d socket编程案例
下一篇: Unity 导出Assetbundle的脚本
我是一纸巾
博客等级 码龄12年 14粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值