当前位置:首页 > 编程笔记 > 正文
已解决

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

来自网友在路上 148848提问 提问时间:2023-09-27 22:57:28阅读次数: 48

最佳答案 问答题库488位专家为你答疑解惑

文章目录

    • 前言
    • 适用场景
    • 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 authenticatedvar clientId = request.ClientNetworkId;// Additional connection data defined by user codevar 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 valuesresponse.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 DisconnectReasonMessageresponse.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 authenticatedvar clientId = request.ClientNetworkId;// Additional connection data defined by user codevar 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 valuesresponse.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 DisconnectReasonMessageresponse.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
查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"Unity之NetCode多人网络游戏联机对战教程(4)--连接申请ConnectionApproval":http://eshow365.cn/6-14889-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!