Unet_自定义NetworkLobbyManager

前言

此部分可以先建立游戏大厅,然后进入游戏,就像大部分rpg游戏一样,在进入游戏前有一个统一的大厅,此处坑甚多耗费大量时间。国内百度出来的基本没靠谱的,一些专栏作家大V也不过是基本翻译了一下用户手册(坑啊),只能通过看youtube视频以及不停的翻阅用户手册解决(很多demo根本没踩到这些坑)。废话不说了,开始(此部分是在上一篇基础上开始的,一些上一篇解释过的操作就不再重复),建议看完此部分后可以看一下下一篇,有助于理解此部分的代码。

1.自定义Lobby

1.1自定义NetworkLobbyManager

自定义脚本LobbyManager并重写NetworkLobbyManager的虚方法,惯例脚本在文末。

1.2 挂载脚本LobbyManager

挂载脚本是有讲究的,此脚本继承自NetworkLobbyManager。NetworkLobbyManager需要两个场景,即lobby场景和游戏场景,前者obby场景为准备场景(可以是像王者荣耀开始前队友列表UI,可以像吃鸡游戏开始之前的小岛场景),后者game场景即为真实游戏进行的场景。同时,对应的 需要两个参数lobby Player和gamePlayer,lobbyPlayer为进入lobby的游戏物体,game Player为真是游戏时的游戏物体。NetworkLobbyManager根据lobby场景中的lobbyPlayer在游戏场景中生成gamePlayer,但是当加载游戏场景后如果lobbyPlayer被销毁,则无法生成gamePlayer,所以加载场景时不能销毁。 而NetworkLobbyManager继承自NetworkManager,所以有DontDestroyOnLoad选项(自定义脚本不需要再继续添加DontDestroyOnLoad选项。而且在某些非常态lobby场景重新加载时(稍后会说到一些可能的重新加载场景)会有多个NetworkLobbyManager),所以生成的lobby Player最好是NetworkLobbyManager的子游戏物体。

1.3 游戏列表

游戏列表其实为了把unityService中建立的游戏进行列表,可供玩家选择加入。不同的游戏是通过LobbyMatch脚本控制,在游戏列表中把每一个LobbyMatch实例化出来

1.4 Player定义

gamePlayer与上上一篇(即example)中NetworkManager的game Player定义相同,必须包含NetworkIdentity和NetworkTransform(如果需要),在增加其他诸如移动,血量控制的脚本。lobbyPlayer则必须继承自Network LobbyPlayer。本篇通过自定义的LobbyPlayer(继承自Network LobbyPlayer)以及Lobby PlayerUI(lobby场景中LobbyPlayer为ui形态),两者脚本在文末。

PS:通过对NetworkLobbyManager应用发现很多坑,所幸基本坑都填上,坑实在太多,但是大部分均在代码中注释清楚,更加详细解释单独在下篇文章中解释。

2.完整脚本

2.1 LobbyManager

using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using System;
using System.Collections.Generic;
using UnityEngine;

public class LobbyManager : NetworkLobbyManager
{
   
    public static LobbyManager theLobbyManager;

    #region OUTER ACITONS
    public Action<MatchInfo> matchCreatedAction;

    public Action<List<MatchInfoSnapshot>> matchListedAction;

    public Action destroyMatchAction;

    public Action dropConnAction;

    public Action clientSceneChangedAction;
    #endregion

    #region HOST CALLBACKS
    public override void OnStartHost()
    {
   
        LogInfo.theLogger.Log("Host create");

        base.OnStartHost();
    }

    public override void OnStopHost()
    {
   
        LogInfo.theLogger.Log("Host stop");

        base.OnStopHost();
    }

    public override void OnStopClient()
    {
   
        LogInfo.theLogger.Log("Host client");

        base.OnStopClient();
    }

    public override void OnStartClient(NetworkClient lobbyClient)
    {
   
        LogInfo.theLogger.Log("Client create");

        base.OnStartClient(lobbyClient);
    }

    public override GameObject OnLobbyServerCreateLobbyPlayer(NetworkConnection conn, short playerControllerId)
    {
   
        int num = 0;
        foreach (var p in lobbySlots)
        {
   
            if (p != null)
            {
   
                num++;
            }
        }

        LogInfo.theLogger.Log("ServerCreateLobbyPlayer:" + num);

        return base.OnLobbyServerCreateLobbyPlayer(conn, playerControllerId); ;
    }

    public override GameObject OnLobbyServerCreateGamePlayer(NetworkConnection conn, short playerControllerId)
    {
   
        LogInfo.theLogger.Log("ServerCreateGamePlayer:" + lobbySlots.Length);

        return base.OnLobbyServerCreateGamePlayer(conn, playerControllerId);
    }

    public override void OnLobbyServerPlayerRemoved(NetworkConnection conn, short playerControllerId)
    {
   
        LogInfo.theLogger.Log("LobbyServerPlayerRemoved");

        base.OnLobbyServerPlayerRemoved(conn, playerControllerId);
    }

    public override void OnServerRemovePlayer(NetworkConnection conn, PlayerController player)
    {
   
        LogInfo.theLogger.Log("ServerRemovePlayer");

        base.OnServerRemovePlayer(conn, player);
    }

    public override void OnLobbyClientSceneChanged(NetworkConnection conn)
    {
   
        LogInfo.theLogger.Log("LobbyClientSceneChanged");

        base.OnLobbyClientSceneChanged(conn);
    }

    public override void OnLobbyServerPlayersReady()//当所有当前加入的player均准备后调用此方法,但加入的玩家数不一定定于maxPlayer
    {
   
        LogInfo.theLogger.Log("LobbyServerPlayersReady:"+lobbySlots.Length);

        //base方法当所有加入的player均准备后进入游戏场景
        //base.OnLobbyServerPlayersReady();

        int readyPlayersNum = 0;

        foreach(var player in lobbySlots)
        {
   
            if (player != null && player.readyToBegin) readyPlayersNum++;
        }

        if (readyPlayersNum == maxPlayers) BeginGame();
 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值