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;
    }
}
相关推荐
略懂而已7 小时前
安装SSL后网站速度变慢?
网络·网络协议·ssl
云上工程笔记8 小时前
RDMA / IB 高速互联 GPU 云对比:多机训练网络性能与价格
网络·gpu算力·gpu
codigger11 小时前
负载均衡到底在干嘛?7 个场景给你说明白
网络·架构·负载均衡
吴建旭 智宅焕1 天前
智能家居全国交付中执行端能力跃迁的架构设计:从标准装调到交付专家的系统化路径
网络·网络协议·智能家居
Eyfcom1 天前
〖全球化架构 05〗跨国网络专线优化:QUIC 协议与 SD-WAN 在跨境传输中的实战
网络·架构·跨境物流快递系统·全球化架构
Dream Cosmos1 天前
传输层协议之UDP
网络·网络协议·udp
鸿蒙开发爱好者1 天前
下班后做的小工具和小游戏,我把它们整理成了 WyanHub
网络·人工智能·职场和发展·个人开发
乐橙开放平台1 天前
海康和大华摄像头能统一管理吗?可以通过 GB28181 或视频融合平台接入
网络·后端·物联网·音视频
张小姐的猫1 天前
【基于 WebSocket 的多用户网页五子棋】—— 项目结构设计与实用工具类模块
网络·websocket·网络协议
QXWZ_IA1 天前
测绘单位采购RTK:设备价格、账号年费、售后,用时间轴分权重
网络·人工智能·安全