当前位置: 首页 > news >正文

【Unity】uNet游戏服务端框架(一)服务端架构设计

更新日期:2025年10月9日。
项目源码:获取源码。

索引

  • uNet游戏服务端框架
    • 一、uNet源码结构
    • 二、uNet架构设计
      • 1.网络玩家 NetworkPlayer
      • 2.网络实体 NetworkEntity
      • 3.网络地图 NetworkMap
      • 4.网络房间 NetworkRoom
      • 5.启动服务端

uNet游戏服务端框架

uNet游戏服务端框架为使用.Net Core开发的高性能、高并发网络游戏服务端框架,基于async / await的多线程架构天然适应IO高并发环境,使用Protobuf进行网络数据交换能够极大的降低带宽和网络延迟,同时使用对象池技术管理服务端中的大多数实例能够显著的降低GC开销。

一、uNet源码结构

uNet解决方案目录中,存在4个项目:

在这里插入图片描述

uNet.Core:uNet框架的核心代码模块。
uNet.Engine:uNet框架中与Unity引擎进行同步交互的功能实现模块。
uNet.Example.ChineseChess:中国象棋的游戏服务端。
uNet.Example.MMO:MMORPG的游戏服务端。

二、uNet架构设计

uNet中,将一个游戏服务端程序中可能出现的所有实例划分为了如下的四类:

类型描述
网络玩家代表网络中的玩家客户端实例
网络实体代表存在于地图、房间中的具备网络同步需求的实体(比如NPC、副本中的BOSS)
网络地图代表可同时容纳大量玩家、大量实体的游戏场景(也即是游戏中的主城)
网络房间代表可同时容纳少量玩家、少量实体的游戏场景(也即是游戏中的副本)

1.网络玩家 NetworkPlayer

网络玩家由NetworkPlayer类表示,一个NetworkPlayer实例即代表了存在于当前服务器中的一名玩家客户端,他的基础属性如下:

    /// <summary>/// 网络玩家/// </summary>public abstract class NetworkPlayer : IObjectPoolable{/// <summary>/// 玩家的ID/// </summary>public long ID { get; private set; }/// <summary>/// 玩家姓名/// </summary>public string? Name { get; protected set; }/// <summary>/// 在本次同步中是否已改变/// </summary>public bool IsDirty { get; set; } = false;/// <summary>/// 心跳包校验码/// </summary>public abstract int HEARTBEAT { get; }/// <summary>/// 常规信息校验码/// </summary>public abstract int NORMAL { get; }//........}

ID:玩家的ID,玩家在当前游戏服务器中的唯一标识符,重新登录后会改变。
Name:玩家的姓名。
IsDirty:在本次同步中是否已改变,在执行网络同步时,只有标记为改变的玩家才会被同步。
HEARTBEAT:心跳包校验码,在心跳机制中,用于鉴别心跳包的校验码。
NORMAL:常规信息校验码,区别于心跳包的常规信息数据包的校验码。

由于NetworkPlayer兼顾了与客户端进行双向通信的使命,所以他自身具备了区别心跳包常规信息数据包的能力。

NetworkPlayer中已封装了用于收、发数据的相关方法(使用Socket收、发),直接调用即可:

        /// <summary>/// 发送数据到客户端/// </summary>/// <param name="bytes">数据内容</param>/// <param name="token">用于取消异步的token</param>/// <returns>是否发送成功</returns>protected async Task<bool> SendDataAsync(byte[]? bytes, CancellationToken token){//代码后续讲解......}/// <summary>/// 从客户端接收数据/// </summary>/// <param name="token">用于取消异步的token</param>/// <returns>网络消息</returns>protected async Task<NetworkMessage?> ReceiveDataAsync(CancellationToken token){//代码后续讲解......}

2.网络实体 NetworkEntity

网络实体由NetworkEntity类表示,除了玩家以外的,存在于地图或副本中的其他需要进行网络同步的实例,都统称为网络实体。

比如副本中的小怪和BOSS,他们需要进行网络同步,以在不同的玩家客户端中表现为相同状态(比如相同的血量,相同的攻击姿态),所以他们网络实体。

但某些NPC,站在原地不动,玩家仅仅能点击他进行对话或接受任务,他们不需要进行网络同步,所以他们不是网络实体。

NetworkEntity的基础属性如下:

    /// <summary>/// 网络实体/// </summary>public abstract class NetworkEntity : IObjectPoolable{/// <summary>/// 实体的ID/// </summary>public long ID { get; private set; }/// <summary>/// 在本次同步中是否已改变/// </summary>public bool IsDirty { get; set; } = false;/// <summary>/// 实体名称/// </summary>public abstract string Name { get; }/// <summary>/// 实体类型/// </summary>public abstract string Type { get; }//......}

ID:实体的ID,实体在当前地图或副本中的唯一标识符,不同类型的实体可能重复。
IsDirty:在本次同步中是否已改变,在执行网络同步时,只有标记为改变的实体才会被同步。
Name:实体的名称,同一类型的实体,他们一般具有相同的名称。
Type:实体的类型,用于在网络环境中区分实体(比如服务端的某个实体Type为Enemy,客户端的相同实体的Type也应该为Enemy,确保在网络同步时能够正确定位到该实体)。

3.网络地图 NetworkMap

网络地图由NetworkMap类表示,一个NetworkMap实例即代表了存在于当前服务器中的一个地图场景,在地图中可容纳大量玩家或实体,玩家与实体之间产生交互并经过网络同步,最终完成一整套的游戏玩法。

交互
交互
收集状态数据
收集状态数据
状态同步
状态同步
玩家
实体
地图

他的基础属性如下:

    /// <summary>/// 网络地图(用于容纳大量网络玩家和大量网络实体)/// </summary>public abstract class NetworkMap : IObjectPoolable{/// <summary>/// 地图名称/// </summary>public abstract string Name { get; }/// <summary>/// 地图类型/// </summary>public abstract string Type { get; }/// <summary>/// 执行网络同步的间隔时间(毫秒)/// </summary>public abstract int SyncInterval { get; }}

Name:地图的名称,同一类型的地图,他们一般具有相同的名称,且地图实例本身就是唯一的。
Type:地图的类型,用于在网络环境中区分地图(比如服务端的某个地图Type为Map1,客户端的相同地图的Type也应该为Map1,确保在网络同步时能够正确定位到该地图)。
SyncInterval:执行网络同步的间隔时间(毫秒),地图拥有自动对其中的玩家和实体进行网络同步的功能,此为2次同步之间的间隔时间,设置得越低同步频率越高,但同时服务端压力也越大,可能导致网络延迟卡顿。

注:通常情况下,地图的同步间隔时间可以设置较长,以降低性能开销。

4.网络房间 NetworkRoom

网络房间由NetworkRoom类表示,一个NetworkRoom实例即代表了存在于当前服务器中的一个房间场景,在房间中可容纳少量玩家或实体,玩家与实体之间产生交互并经过网络同步,最终完成一整套的游戏玩法。

交互
交互
收集状态数据
收集状态数据
状态同步
状态同步
玩家
实体
房间

由于同一类型的NetworkRoom是可以创建多个的,所以他们在大多数时候也被叫做副本

他的基础属性如下:

    /// <summary>/// 网络房间(用于容纳少量网络玩家和少量网络实体)/// </summary>public abstract class NetworkRoom : IObjectPoolable{/// <summary>/// 房间ID/// </summary>public long ID { get; private set; }/// <summary>/// 房间名称/// </summary>public abstract string Name { get; }/// <summary>/// 房间类型/// </summary>public abstract string Type { get; }/// <summary>/// 执行网络同步的间隔时间(毫秒)/// </summary>public abstract int SyncInterval { get; }}

ID:房间的ID,在当前服务器中的唯一标识符,不同类型的房间可能重复。
Name:房间的名称,同一类型的房间,他们一般具有相同的名称。
Type:房间的类型,用于在网络环境中区分房间(比如服务端的某个房间Type为Room1,客户端的相同房间的Type也应该为Room1,确保在网络同步时能够正确定位到该房间)。
SyncInterval:执行网络同步的间隔时间(毫秒),房间拥有自动对其中的玩家和实体进行网络同步的功能,此为2次同步之间的间隔时间,设置得越低同步频率越高,但同时服务端压力也越大,可能导致网络延迟卡顿。

注:通常情况下,房间的同步间隔时间可以设置较短,以带来更流畅的体验。

uNet的网络同步采用的是状态同步的方式,而网络同步的时机为固定频率同步,这不一定适合所有游戏,只是我们本系列教程所采用的方式,当然,其他方式(比如帧同步)后续可能也会考虑。

5.启动服务端

启动服务端的话将非常简单,比如通过查看MMORPG的服务端入口函数Main,将看到极简的代码:

namespace uNet.Example.MMO
{class Program{static void Main(string[] args){//定义服务端配置信息,比如监听的IP地址、端口号,玩家类型(继承至NetworkPlayer,同一游戏服务端中只能存在一种玩家类型)ServerConfig config = new ServerConfig("127.0.0.1", 11000, typeof(MMO_Player), 10, 20);//创建服务端入口ServerEntry entry = new ServerEntry(config);//创建一个地图(比如这里是初始地图:暴风要塞)entry.CreateMap<MMO_BeginnerMap>();//启动服务端entry.Start();//启用常规日志的打印显示Log.IsEnableInfo = true;//按下ESC键退出程序ConsoleKeyInfo consoleKeyInfo = Console.ReadKey();while (consoleKeyInfo.Key != ConsoleKey.Escape){consoleKeyInfo = Console.ReadKey();}}}
}

服务端为控制台程序,启动完成后如下:

在这里插入图片描述

http://www.dtcms.com/a/460865.html

相关文章:

  • 深圳企业营销型网站建设优创智汇高端网站建设
  • mysql数据库备份
  • 22.shell编程实战(一)
  • PyTorch、ONNX Runtime、Hugging Face、NVIDIA Triton 和 LangChain 五个概念的关系详解
  • 【云原生】Neo4j 图数据库从搭建到项目使用深度详解
  • 关于网站开发的技术博客女装网站模板
  • Kubernetes(K8s)全场景命令宝典:从新手入门到故障排查全覆盖
  • 基于protobuf实现网络版本通讯录(protobuf 0基础可看)
  • 开源3d数字人学习笔记2025
  • 四大名著智能可视化推演平台
  • 成像系统(十四-2:《手机影像系统揭秘(二):ISP后端处理 - 画质增强与风格化》):从LED冬奥会、奥运会及春晚等大屏,到手机小屏,快来挖一挖里面都有什么
  • jsp ajax网站开发典型实例佟年给韩商言做的网站
  • 【算法】二分查找(二)查找边界二分
  • 【QT】采用fcitx5框架Ubuntu支持中文输入,QT不支持,解决?
  • 在Robosuite中如何使用Xbox游戏手柄操控mujoco仿真中的机械臂?
  • 数据民主化实践:ChatBI赋能全民数据分析
  • 零基础学AI大模型之LangChain链
  • 拱墅区网站建设网页培训机构
  • 潮州网站建设公司青岛市公共资源交易网
  • 告别重复数据烦恼!MySQL ON DUPLICATE KEY UPDATE 优雅解决存在更新/不存在插入难题
  • 开源项目安全性
  • 找网站建设都需要注意哪些云优化 网站建设
  • dockerfile构建案例
  • UiPath2025笔记第七节:B端Ai操控C端Rpa机器人
  • C++ 经典数组算法题解析与实现教程
  • 详解SOA架构,微服务架构,中台架构以及他们之间的区别和联系
  • 【C++学习笔记】伪随机数生成
  • Unity笔记(十二)——角色控制器、导航寻路系统
  • 关于嵌入式硬件需要了解的基础知识
  • 个人电脑做服务器网站目录型搜索引擎有哪些