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;
    }
}
相关推荐
AnalogElectronic8 小时前
linux 测试网络和端口是否连通的命令详解
linux·网络·php
Rust研习社9 小时前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust
灰子学技术9 小时前
Envoy HTTP 流量层面的 Metric 指标分析
网络·网络协议·http
上海云盾-小余9 小时前
海外恶意 UDP 攻击溯源:分层封禁策略与业务兼容平衡方案
网络·网络协议·udp
智慧光迅AINOPOL9 小时前
校园全光网建设指南:从架构到调优,打造稳定高体验校园网络
网络·全光网解决方案·全光网·酒店全光解决方案·泛住宿全光网解决方案
被摘下的星星10 小时前
Internet 的域名系统:从“名字”到“地址”的翻译官
网络
Diros1g11 小时前
如何通过普通网线给另一个设备供网
网络·网络协议
beyond阿亮12 小时前
IEC104 Client Simulator - IEC104 主站/客户端模拟器 仿真器免费使用教程
运维·服务器·网络
(Charon)12 小时前
【C++/Qt】Qt 封装 TCP 客户端底层 Network 类:连接、收发、自动测试与错误处理
服务器·网络·qt·tcp/ip
KKKlucifer12 小时前
日志审计与行为分析在安全服务中的应用实践
网络·人工智能·安全