Mirror网络库插件使用6

游戏对象

网络游戏对象

需要在玩家间同步,附加了NetworkIdentity组件的游戏对象。
非网络游戏对象

不需要在玩家间进行同步,没有附加NetworkIdentity组件的游戏对象。

玩家游戏对象

玩家游戏对象属于网络游戏对象。

在每个客户端上,属于该客户端的玩家对象被标记为本地玩家,其余玩家对象为远程副本。

本地玩家标识:isLocalPlayer(NetworkBehaviour上属性)是真。

玩家游戏对象在其他客户端有一个自己的副本对象。

服务器持有所有玩家,负责状态计算和同步。

示例:

服务器有所有客户端的副本;

客户端1有本机角色player1和远程角色player2;

客户端2有本机角色player2和远程角色player1。

自定义角色生成

默认情况下,Mirror的NetworkManager会自动生成Player角色。

这导致一个问题,如果player预制体是一个模型,那么所有客户端的player都是一样的。

自定义角色生成可以解决这个问题。

示例:点击UI,创建不同的player

  1. 新建场景,创建空对象,命名为NetworkManager,添加组件SpawnSampleNetworkManager,NetworkManagerHUD,KcpTransport;
  2. 创建cube,capsule,sphere作为不同的player,分别添加组件NetworkIdentity,移除场景中的player;
  3. 新建空对象,命名为PlayerSelector,添加组件PlayerSelector;
  4. NetworkManager对象设置KcpTransport,角色列表;
  5. PlayerSelector对象引用Networkmanager。

注意:

player预制体可以手动添加到Registered Sapwnable Prefabs列表中;

也可以使用代码动态添加player。

如果没有上述任一操作,客户端不会生成对应的对象。

脚本

SpawnMessage用于传递用户选择的playerIndex

csharp 复制代码
using Mirror;
public struct SpawnMessage : NetworkMessage
{
    public int prefabIndex;
}

SpawnSampleNetworkManager中注册角色预制体列表,注册角色生成逻辑,触发客户端断开事件;

csharp 复制代码
using System;
using Mirror;
using UnityEngine;
public class SpawnSampleNetworkManager : NetworkManager
{
    [Serializable]
    public class SpawnPlayer
    {
        public GameObject playerPrefab;
        public Vector3 spawnPosition;
    }

    [Header("角色列表")]
    public SpawnPlayer[] playerPrefabs;

    public event Action OnClientDisconnectAction;

    public override void Awake()
    {
        base.Awake();
        //玩家预制体加入spawnPrefabs
        for (int i = 0; i < playerPrefabs.Length; i++)
        {
            if (!spawnPrefabs.Contains(playerPrefabs[i].playerPrefab))
                spawnPrefabs.Add(playerPrefabs[i].playerPrefab);
        }
    }

    public override void OnStartServer()
    {
        NetworkServer.RegisterHandler<SpawnMessage>(OnSpawnMessage);
    }

    private void OnSpawnMessage(NetworkConnectionToClient client, SpawnMessage message)
    {
        if (message.prefabIndex < 0 || message.prefabIndex >= playerPrefabs.Length)
        {
            Debug.LogError($"Invalid prefab index {message.prefabIndex}");
            return;
        }
        SpawnPlayer spwanPlayer = playerPrefabs[message.prefabIndex];
        GameObject player = Instantiate(spwanPlayer.playerPrefab, spwanPlayer.spawnPosition, Quaternion.identity);
        NetworkServer.AddPlayerForConnection(client, player);
    }

    public override void OnStopServer()
    {
        NetworkServer.UnregisterHandler<SpawnMessage>();
    }

    public override void OnClientDisconnect()
    {
        OnClientDisconnectAction?.Invoke();
    }
}

PlayerSelector使用OnGUI绘制UI,用户点击UI创建不同的player,客户端断开连接重置选择。

csharp 复制代码
using System;
using Mirror;
using UnityEngine;

[Serializable]
public class PlayerSelector : MonoBehaviour
{
    [SerializeField] SpawnSampleNetworkManager manager;

    private bool hasSelectedPlayer = false;
    public Vector2 offest;

    void OnEnable()
    {
        manager.OnClientDisconnectAction += OnClientDisconnected;
    }

    void OnDisable()
    {
        manager.OnClientDisconnectAction -= OnClientDisconnected;
    }

    private void OnClientDisconnected()
    {
        hasSelectedPlayer = false;
    }

    private void OnGUI()
    {
        if (hasSelectedPlayer == false && NetworkClient.isConnected)
        {
            GUILayout.BeginArea(new Rect(offest.x, offest.y, 100f, Screen.height));
            if (GUILayout.Button("选择角色1"))
                SendMessageToServer(0);
            if (GUILayout.Button("选择角色2"))
                SendMessageToServer(1);
            if (GUILayout.Button("选择角色3"))
                SendMessageToServer(2);
            GUILayout.EndArea();
        }
    }

    private void SendMessageToServer(int index)
    {
        if (hasSelectedPlayer == true)
            return;
        SpawnMessage message = new SpawnMessage
        {
            prefabIndex = index
        };
        NetworkClient.Send(message);
        hasSelectedPlayer = true;
    }
}
相关推荐
z2023050815 小时前
RDMA之RoCEv2 无损网络PFC 、DCQCN 和ECN (7)
linux·服务器·网络·人工智能·ai
凯瑟琳.奥古斯特15 小时前
传输层核心功能解析
开发语言·网络·职场和发展
jiayong2316 小时前
前端面试题库 - 浏览器与网络篇
前端·网络·面试
pengyi87101516 小时前
共享 IP 防封维护策略,降低被封率、延长 IP 寿命
网络·网络协议·tcp/ip
制造业的搬运工17 小时前
高端电路板哪家好:专业视角下的选择逻辑
网络·pcb工艺·pcb
Yeats_Liao17 小时前
物联网接入层技术剖析(二):epoll到底是怎么工作的
java·linux·网络·物联网·信息与通信
机器学习之心17 小时前
基于贝叶斯优化超参数的图卷积网络(BO-GCN)分类预测模型(附实验文档+Matlab代码)
网络·matlab·分类·分类预测模型·bo-gcn
上海云盾-小余17 小时前
内网终端安全管控:筑牢企业内部网络入侵防火墙
服务器·网络·安全
思茂信息17 小时前
CST案例:可调谐全硅手性超表面在太赫兹频段
网络·人工智能·算法·重构·cst·电磁仿真
Bat U18 小时前
JavaEE|网络原理TCP/IP
网络·网络协议·tcp/ip