通过示例在 Unity 和 NodeJS 上的游戏中创建安全、快速的多人游戏

介绍

规划多人游戏开发方法 – 在整个项目的进一步开发中发挥着最重要的作用之一,因为它包含了我们在创建真正高质量的产品时应该考虑的许多标准。在今天的宣言教程中,我们将看一个方法示例,该方法使我们能够创建真正快速的游戏,同时尊重所有安全和反违规规则。

通过示例在 Unity 和 NodeJS 上的游戏中创建安全、快速的多人游戏

所以,让我们定义我们的主要标准:

多人游戏需要一种特殊的方法来管理网络同步,尤其是在实时情况下。 二进制协议用于加速客户端之间的数据同步,反应字段将有助于以最小的延迟和节省内存来更新玩家位置。服务器权限是一项重要原则,关键数据仅在服务器上处理,确保游戏完整性并防止作弊。然而,为了让我们最大限度地提高性能 – 服务器只进行关键更新,剩下的交给客户端反作弊。实施客户端反投诉,以便在服务器上不增加负载的情况下处理不太关键的数据

通过示例在 Unity 和 NodeJS 上的游戏中创建安全、快速的多人游戏

架构的主要组成部分

客户端(unity):客户端负责显示游戏状态,将玩家操作发送到服务器并从服务器接收更新。这里还使用反应字段来动态更新玩家位置。服务器端(node.js):服务器处理关键数据(例如,移动、碰撞和玩家动作)并将更新发送到所有连接的客户端。非关键数据可以在客户端上处理并使用服务器转发到其他客户端。二进制协议:二进制数据序列化用于减少传输的数据量并提高性能。同步:提供客户端之间数据的快速同步,以最大程度地减少延迟并确保流畅的游戏体验。客户端反作弊:它用于我们可以在客户端上更改并发送给其他客户端的数据。

第 1 步:在 node.js 中实现服务器

首先,您需要在 node.js 上设置一个服务器。服务器将负责所有关键计算并将更新的数据传输给玩家。

安装环境
要在 node.js 上创建服务器,请安装必要的依赖项:

mkdir multiplayer-game-servercd multiplayer-game-servernpm init -ynpm install socket.io

socket.io可以轻松地使用web套接字实现客户端和服务器之间的实时双向通信。

基本服务器实现
让我们创建一个简单的服务器,它将处理客户端连接、检索数据、计算关键状态并在所有客户端之间同步它们。

// create a simple socket io serverconst io = require('socket.io')(3000, {    cors: {        origin: '*'    }});// simple example of game stateslet gamestate = {};let playerspeedconfig = {    maxx: 1,    maxy: 1,    maxz: 1};// work with new connectionio.on('connection', (socket) => {    console.log('player connected:', socket.id);    // initialize player state for socket id    gamestate[socket.id] = { x: 0, y: 0, z: 0 };    // work with simple player command for movement    socket.on('playermove', (data) => {        const { id, dx, dy, dz } = parseplayermove(data);        // check maximal values        if(dx > playerspeedconfig.maxx) dx = playerspeedconfig.maxx;        if(dy > playerspeedconfig.maxy) dx = playerspeedconfig.maxy;        if(dz > playerspeedconfig.maxz) dx = playerspeedconfig.maxz;        // update game state for current player        gamestate[id].x += dx;        gamestate[id].y += dy;        gamestate[id].z += dz;        // send new state for all clients        const updateddata = serializegamestate(gamestate);        io.emit('gamestateupdate', updateddata);    });    // work with unsafe data    socket.on('dataupdate', (data) => {        const { id, unsafe } = parseplayerunsafe(data);        // update game state for current player        gamestate[id].unsafevalue += unsafe;        // send new state for all clients        const updateddata = serializegamestate(gamestate);        io.emit('gamestateupdate', updateddata);    });    // work with player disconnection    socket.on('disconnect', () => {        console.log('player disconnected:', socket.id);        delete gamestate[socket.id];    });});// simple parse our binary datafunction parseplayermove(buffer) {    const id = buffer.tostring('utf8', 0, 16); // player id (16 bit)    const dx = buffer.readfloatle(16);         // delta x    const dy = buffer.readfloatle(20);         // delta  y    const dz = buffer.readfloatle(24);         // delta  z    return { id, dx, dy, dz };}// simple parse of unsafe datafunction parseplayerunsafe(buffer) {    const id = buffer.tostring('utf8', 0, 16); // player id (16 bit)    const unsafe = buffer.readfloatle(16);     // unsafe float    return { id, unsafe };}// simple game state serialization for binary protocolfunction serializegamestate(gamestate) {    const buffers = [];    for (const [id, data] of object.entries(gamestate)) {        // player id        const idbuffer = buffer.from(id, 'utf8');        // position (critical) buffer        const posbuffer = buffer.alloc(12);        posbuffer.writefloatle(data.x, 0);        posbuffer.writefloatle(data.y, 4);        posbuffer.writefloatle(data.z, 8);        // unsafe data buffer        const unsafebuffer = buffer.alloc(4);        unsafebuffer.writefloatle(data.unsafevalue, 0);        // join all buffers        buffers.push(buffer.concat([idbuffer, posbuffer, unsafebuffer]));    }    return buffer.concat(buffers);}

此服务器执行以下操作:

处理客户端连接。接收二进制格式的玩家移动数据,验证它,更新服务器上的状态并将其发送到所有客户端。以最小延迟同步游戏状态,使用二进制格式来减少数据量。简单地转发来自客户端的不安全数据。

要点:

服务器权限:所有重要数据均在服务器上处理和存储。客户端仅发送操作命令(例如,位置变化增量)。二进制数据传输:使用二进制协议可以节省流量并提高网络性能,特别是对于频繁的实时数据交换。

第2步:在unity上实现客户端部分

现在让我们在 unity 上创建一个与服务器交互的客户端部分。

要将 unity 连接到 socket.io 上的服务器,您需要连接专为 unity 设计的库。在这种情况下,我们不受任何特定实现的约束(事实上它们都是相似的),而只是使用一个抽象示例。

使用反应字段进行同步
我们将使用反应字段来更新玩家位置。这将使我们能够更新状态,而无需通过 update() 方法检查每个帧中的数据。当数据状态发生变化时,反应字段会自动更新游戏中对象的视觉表示。

要获得反应性属性功能,您可以使用 unirx。

unity 上的客户端代码
让我们创建一个脚本来连接到服务器、发送数据并通过反应字段接收更新。

using UnityEngine;using SocketIOClient;using UniRx;using System;using System.Text;// Basic Game Client Implementationpublic class GameClient : MonoBehaviour{    // SocketIO Based Client    private SocketIO client;    // Our Player Reactive Position    public ReactiveProperty playerPosition = new ReactiveProperty(Vector3.zero);    // Client Initialization    private void Start()    {        // Connect to our server        client = new SocketIO("http://localhost:3000");        // Add Client Events        client.OnConnected += OnConnected;    // On Connected        client.On("gameStateUpdate", OnGameStateUpdate); // On Game State Changed        // Connect to Socket Async        client.ConnectAsync();        // Subscribe to our player position changed        playerPosition.Subscribe(newPosition => {            // Here you can interpolate your position instead            // to get smooth movement at large ping            transform.position = newPosition;        });        // Add Movement Commands        Observable.EveryUpdate().Where(_ => Input.GetKey(KeyCode.W)).Subscribe(_ => ProcessInput(true));        Observable.EveryUpdate().Where(_ => Input.GetKey(KeyCode.S)).Subscribe(_ => ProcessInput(false));    }    // On Player Connected    private async void OnConnected(object sender, EventArgs e)    {        Debug.Log("Connected to server!");    }    // On Game State Update    private void OnGameStateUpdate(SocketIOResponse response)    {        // Get our binary data        byte[] data = response.GetValue();        // Work with binary data        int offset = 0;        while (offset < data.Length)        {            // Get Player ID            string playerId = Encoding.UTF8.GetString(data, offset, 16);            offset += 16;            // Get Player Position            float x = BitConverter.ToSingle(data, offset);            float y = BitConverter.ToSingle(data, offset + 4);            float z = BitConverter.ToSingle(data, offset + 8);            offset += 12;            // Get Player unsafe variable            float unsafeVariable = BitConverter.ToSingle(data, offset);            // Check if it's our player position            if (playerId == client.Id)                playerPosition.Value = new Vector3(x, y, z);            else                UpdateOtherPlayerPosition(playerId, new Vector3(x, y, z), unsafeVariable);        }    }    // Process player input    private void ProcessInput(bool isForward){        if (isForward)            SendMoveData(new Vector3(0, 0, 1)); // Move Forward        else            SendMoveData(new Vector3(0, 0, -1)); // Move Backward    }    // Send Movement Data    private async void SendMoveData(Vector3 delta)    {        byte[] data = new byte[28];        Encoding.UTF8.GetBytes(client.Id).CopyTo(data, 0);        BitConverter.GetBytes(delta.x).CopyTo(data, 16);        BitConverter.GetBytes(delta.y).CopyTo(data, 20);        BitConverter.GetBytes(delta.z).CopyTo(data, 24);        await client.EmitAsync("playerMove", data);    }    // Send any unsafe data    private async void SendUnsafeData(float unsafeData){        byte[] data = new byte[20];        Encoding.UTF8.GetBytes(client.Id).CopyTo(data, 0);        BitConverter.GetBytes(unsafeData).CopyTo(data, 16);        await client.EmitAsync("dataUpdate", data);    }    // Update Other players position    private void UpdateOtherPlayerPosition(string playerId, Vector3 newPosition, float unsafeVariable)    {        // Here we can update other player positions and variables    }    // On Client Object Destroyed    private void OnDestroy()    {        client.DisconnectAsync();    }}

第 3 步:优化同步和性能

为了确保流畅的游戏体验并最大程度地减少同步期间的延迟,建议:

使用插值:客户端可以使用插值来平滑服务器更新之间的移动。这可以补偿较小的网络延迟。批量数据发送:不要按每一步发送数据,而是使用批量发送。例如,每隔几毫秒发送一次更新,这将减少网络负载。 降低更新频率:将发送数据的频率降低到合理的最低限度。例如,对于大多数游戏来说,每秒更新 20-30 次可能就足够了。

如何简化二进制协议的使用?

为了简化您使用二进制协议的工作 – 创建数据处理的基本原理以及与其交互的方案。

快写红薯通AI 快写红薯通AI

快写红薯通AI,专为小红书而生的AI写作工具

快写红薯通AI 57 查看详情 快写红薯通AI

对于我们的示例,我们可以采用一个基本协议,其中:
1) 前 4 位是用户发出的请求的最大值(例如 0 – 移动玩家,1 – 射击等);
2) 接下来的 16 位是我们客户的 id。
3) 接下来我们填充通过循环传递的数据(一些网络变量),其中存储变量的 id、到下一个变量开头的偏移量(以字节为单位)、变量的类型和它的价值。

为了方便版本和数据控制 – 我们可以以方便的格式(json / xml)创建客户端-服务器通信模式,并从服务器下载一次,以便根据该模式进一步解析我们的二进制数据以获得所需的内容我们的 api 版本。

客户端反作弊

在服务器上处理所有数据是没有意义的,其中一些数据更容易在客户端修改并发送到其他客户端。

为了让你在这个方案中更加安全 – 你可以使用客户端防黑客系统来防止内存黑客 – 例如,我的 gameshield – 一个免费的开源解决方案。

结论

我们举了一个简单的例子,在 unity 上使用 node.js 服务器开发多人游戏,所有关键数据都在服务器上处理,以确保游戏的完整性。使用二进制协议传输数据有助于优化流量,而 unity 中的反应式编程可以轻松同步客户端状态,而无需使用 update() 方法。

这种方法不仅可以提高游戏性能,还可以通过确保所有关键计算都在服务器而不是客户端上执行来增强对作弊的保护。

当然,一如既往地感谢您阅读这篇文章。如果您在组织多人项目架构方面仍有任何疑问或需要帮助 – 我邀请您加入我的 discord

您还可以在我的困境中为我提供很多帮助,并支持发布新文章以及为开发人员免费提供的库和资源:

我的不和谐 | 我的博客 | 我的 github

btc: bc1qef2d34r4xkrm48zknjdjt7c0ea92ay9m2a7q55

eth: 0x1112a2ef850711df4de9c432376f255f416ef5d0
usdt (trc20):trf7sli6trtnau6k3pvvy61bzqkhxdcrlc

以上就是通过示例在 Unity 和 NodeJS 上的游戏中创建安全、快速的多人游戏的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/456730.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月8日 01:44:04
下一篇 2025年11月8日 01:45:02

相关推荐

  • 比特币价格崩溃?分析师警告信号潜在的下降!

    比特币价格逼近105,000美元,但部分分析师已发出警示信号。btc是否会暴跌至60,000美元?深入解读图表与专家观点! 比特币高位震荡,分析师警示可能回调风险! 比特币正处高位运行,但价格是否即将迎来大幅下跌?多位分析师指出市场存在回调迹象。会否跌至6万美元区间? 分析师预警:比特币或回测60,…

    2025年12月8日
    000
  • Dogecoin的价格预测:骑突破波还是面对蘸酱?

    dogecoin关键价格节点:能否突破$0.35?还是回落至$0.10?深度解析未来走势与重要技术位。 Dogecoin价格展望:迎接突破,还是面临回调? Dogecoin(DOGE)正处在趋势转折的关键阶段,市场关注其重要的技术突破点,这将可能决定它下一步是迎来上涨浪潮,还是陷入下跌调整。它是会飙…

    2025年12月8日
    000
  • GWAR币交易平台软件有哪些?GWAR币交易软件前五推荐

    在数字货币的浪潮中,GWAR币作为一种新兴的加密资产,吸引了越来越多的关注。然而,对于许多跃跃欲试的投资者来说,一个关键问题摆在眼前:GWAR币交易平台软件有哪些? 选择一个安全可靠、功能完善的交易平台至关重要,它直接关系到您的投资体验和资金安全。本文将深入探讨GWAR币交易平台的选择,并为您推荐当…

    2025年12月8日 好文分享
    000
  • 易欧okex最新官网地址 okex易欧网页入口

    okx易欧不仅仅是一个交易平台,它更是一个生态系统,致力于为用户提供全面的数字资产服务。从现货交易到衍生品交易,从法币交易到defi挖矿,okx易欧涵盖了数字资产领域的各种需求。其强大的技术支持、严格的安全措施和不断创新的产品,使其在竞争激烈的市场中脱颖而出。对于新手用户,okx易欧提供了友好的用户…

    2025年12月8日
    000
  • AISHIB币去哪里买?AISHIB币交易所有哪些?

    AISHIB币,作为加密货币领域的新兴力量,其购买渠道和交易平台的选择,是每一位潜在投资者必须了解的关键信息。 想要踏入AISHIB币的投资世界,了解“AISHIB币去哪里买?AISHIB币交易所有哪些?”这两个核心问题至关重要。毕竟,选择安全可靠的交易平台,是保障资产安全的第一步。 目前,AISH…

    2025年12月8日
    000
  • BlackRock的Buidl Fund and USDTB:机构Defi的新时代?

    blackrock的buidl基金在defi领域掀起波澜,与ethena的usdtb实现全天候互换。这是否预示着机构参与加密资产的未来? BlackRock Buidl基金与USDTB:机构级DeFi新纪元? BlackRock推出的Buidl基金正在引发数字金融圈的广泛讨论。通过与Ethena旗下…

    2025年12月8日
    000
  • HASH币用什么app买?HASH哪个交易所可以买到?

    你是否也对新兴的加密货币HASH币充满好奇,渴望了解它并进行投资?你是否正在苦苦寻找能够安全可靠地购买HASH币的平台?别担心,这篇文章将为你揭开谜底,详细介绍可以购买HASH币的app和交易所,助你轻松踏入HASH币的投资之旅。 目前,可以购买HASH币的交易所相对较少,你需要仔细甄别。以下是一些…

    2025年12月8日
    000
  • Circle,Stablecoin和Rally:Crypto最新繁荣的纽约分钟

    随着《天才法案》的通过,circle股价暴涨,为stablecoin监管铺路。这是稳定币夏日狂欢的开端,还是又一场华尔街泡沫? 系好安全带,各位!加密圈正热议不休,而这一切的核心是Circle、稳定币以及引发市场躁动的集体上涨。美国参议院通过的《天才法案》,推动了Circle股票的飙升,可能成为稳定…

    2025年12月8日
    000
  • 2025币圈交易平台有哪些 2025币圈数字货币交易平台最新排名一览

    2025年数字货币交易平台排名前十依次为币安、OKX、火币、Coinbase、Kraken、Bitfinex、KuCoin、Gemini、Binance US和Crypto.com。币安以丰富的交易对、强大的流动性和多重安全措施保持领先;OKX凭借低手续费和区块链生态系统稳居前列;火币以合规性及亚洲…

    2025年12月8日
    000
  • 2025年,如何在币圈选对交易所买U币?

    2025年选择一家合适的交易所购买U币(通常指USDT,一种与美元挂钩的稳定币)至关重要。这不仅仅关乎便捷性,更直接影响到你的资金安全和交易体验。想象一下,你辛辛苦苦研究了几个月的项目,终于决定入场,却发现交易所提币困难重重,或者交易深度不足导致滑点严重,那将是多么令人沮丧的事情。 在2025年购买…

    2025年12月8日
    000
  • 好用的数字货币交易平台 2025最好用的数字货币交易平台盘点

    2025年最好用的数字货币交易平台包括Binance、OKX、Huobi等,其中Binance凭借其庞大的用户群体、丰富的交易品种及强大的技术实力持续领先,并提供现货、合约、杠杆、期权等多种交易方式;使用币安需先注册账号、完成KYC身份验证、充值后方可交易,最后可提现;OKX以合约交易著称,提供永续…

    2025年12月8日
    000
  • 怎么下载欧意交易所 欧意使用教程

    在%ignore_a_1%日益普及的今天,选择一个安全、便捷、功能强大的交易平台至关重要。欧意交易所(okx)作为全球领先的数字资产交易平台之一,凭借其丰富的交易品种、强大的安全保障和流畅的用户体验,吸引了众多投资者的目光。本教程将详细介绍如何下载欧意交易所,并提供全面的使用指南,帮助您快速上手,安…

    2025年12月8日
    000
  • Solana ETF手表:DTCC列出Sparks SEC批准嗡嗡声!

    vaneck的solana etf(vsol)在dtcc ingites上出现,引发市场对sec批准的期待。solana会成为下一个获批etf的加密货币吗?现在或是入场时机。 Solana ETF动态:DTCC上线引发SEC批准猜测! Solana ETF的故事正逐步升温!由VanEck提出的实物支…

    2025年12月8日
    000
  • Kucoin列出了Namada(NAM)的象征奖励Gempool:深度潜水

    kucoin上线了namada(nam),并通过gempool farming活动提供代币奖励。了解如何参与,并探讨这一举措对隐私优先型加密货币的潜在影响。 Kucoin上架NAMADA(NAM)显示出市场对注重隐私的区块链解决方案的兴趣正在上升。通过Gempool农场活动发放2,000,000枚N…

    2025年12月8日
    000
  • USDT泰达币是什么?为何有脱钩风险?2025年USDT 泰达币完整介绍

    USDT泰达币是什么?2025年USDT 泰达币完整介绍 USDT 泰达币基本信息 中文名称:泰达币 英文名称:Tether USDt 常用缩写: USDT 官网:https://tether.to/  创始人:USDT 最早于2014 年6 月由Brock Pierce, Craig Sellar…

    2025年12月8日
    000
  • XRP,云采矿和区块链:加密访问的新时代

    探索xrp、云挖矿与区块链技术的交汇点,使加密货币收益变得前所未有的轻松。 嘿,加密爱好者们!你有没有想过在睡觉的时候也能赚钱?今天就让我们一起深入了解XRP、云挖矿以及区块链的世界——就像在旧裤子里发现一张二十美元纸币一样令人惊喜,只不过这次更酷。 到底发生了什么? 现在是2025年,加密货币已经…

    2025年12月8日
    000
  • 2025年十大好用的虚拟币交易所平台 十大虚拟币交易所最新排名

    币圈公认交易所榜单中,Binance、OKX、Huobi等平台因技术实力和交易品种丰富而领先。要注册币安账户,您需要:1.访问官网;2.点击“注册”按钮,选择邮箱或手机号注册;3.填写相关信息;4.完成人机验证;5.阅读并同意服务条款;6.点击“注册”按钮完成注册;7.登录邮箱/手机号完成验证;8.…

    2025年12月8日 好文分享
    000
  • Stablecoins,市值和法规:导航加密货币景观

    潜入稳定币市场,探索市值走向、监管进程与新兴创新项目。 Stablecoins,市值与合规:解读加密货币格局 稳定币市场正经历显著变化,这主要受到机构投资者关注度上升以及监管政策逐步明朗的推动。我们将深入分析市值变化、法规进展与技术创新的核心趋势。 稳定币市值:双雄争霸的局面 目前稳定币市场由两大巨…

    2025年12月8日
    000
  • 2025公认好用的数字货币交易所排行榜汇总

    2025年十大数字货币交易App排名依次为Binance、OKX、Huobi、Coinbase、Kraken、Bitstamp、Gemini、Crypto.com、KuCoin和Bitfinex。选择交易平台需关注安全性、交易费用、支持币种、用户体验及流动性,具体步骤包括查看安全记录、比较费用、确认…

    2025年12月8日 好文分享
    000
  • 系绳,USDT和Stablecoins:浏览数字美元的野外西部

    看看绳索,usdt和stablecoins不断发展的景观,探索监管影响,市场趋势和潜在的陷阱。 Tether(USDT)与Stablecoins正在加密货币领域引发热议。从政策变化到市场份额争夺,让我们一起深入探讨最新的发展动态、行业走向以及它们对你的影响。 稳定币的崛起 Stablecoin市场正…

    2025年12月8日
    000

发表回复

登录后才能评论
关注微信