zoukankan      html  css  js  c++  java
  • NetworkManager网络通讯_NetworkManager(二)

    本文主要来实现一下自定UI(实现HUD的功能),并对Network Manger进行深入的讲解。

    1)自定义manager

    创建脚本CustomerUnetManger,并继承自NetworkManger,并对相关虚函数进行重载,并简单写了几个外部调用方法。完整脚本在文末,部分截图如下:

    其中LogInfo为debug用,完整脚本在文末

    2)UI脚本CustomerUnetMainMenu

    编写脚本,实现自定义新建Server client 以及host,再次着重说一下原NetworkMangerHUD脚本中的第四个方法,即NetworkManger中的matchmaker。matchmaker通过unity提供的网络服务,建立游戏,然后通过你自己生成的exe就可以获取到建立的游戏列表,然后可以加入游戏:

    首先开启matchmaker

        /// <summary>
        /// UI调用,MatchMaker
        /// </summary>
        public void StartMatchMaker_()
        {
            if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
            {
                StartMatchMaker();
                matchMode = true;
            }
        }

    然后建立游戏

        /// <summary>
        /// UI调用,创建比赛
        /// </summary>
        public void CreateMatch_()
        {
            if (matchMaker != null)
            {
                matchMaker.CreateMatch("LLMatch", 3, true, "", "", "", 0, 0, OnMatchCreate);
            }
        }

    获取游戏列表(获取列表并UI显示时需要脚本match Button)

    matchMaker.ListMatches(0, 5, "", true, 0, 0, OnMatchList);

    加入游戏

        /// <summary>
        /// 加入指定的比赛
        /// 对于建立比赛的player,本身已经在游戏中,所以不能再次加入(已经生成host)
        /// 对于建立比赛的player,在加入其他游戏时先取消比赛(DestroyMatch)
        /// 对于加入比赛的player,只能加入一次,不能重复加入(已经生成client)
        /// 对于加入比赛的Player,在重复加入或者加入其他游戏之前先断开连接(DropConnection)
        /// 本程序为demo,上述问题不做处理
        /// </summary>
        /// <param name="jointMatch"></param>
        public void JoinMatch(MatchInfoSnapshot jointMatch)
        {
            if (matchMaker == null) StartMatchMaker();
    
            matchMaker.JoinMatch(jointMatch.networkId, "", "", "", 0, 0, OnMatchJoined);//调用此方法时生成client
        }

    3)此部分到此基本结束没有太大问题,一些注意事项已经在代码中注释,至于如何退出比赛等会再下一篇LobbyManager中进行解释,下边时此工程的所有脚本文件。再次说明一下,玩家预制体等均采用上一篇。此工程为demo,所以UI简陋,可能会有不友好的操作或者逻辑bug

    //——————————————————————————————脚本————————————————————————————//

    using System;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Networking;
    using UnityEngine.Networking.Match;
    
    public class CustomerUnetManger : NetworkManager
    {
        public Action<List<MatchInfoSnapshot>> ListMatchAction;
    
        private float refreshTime = 0;
        private bool matchMode = false;
    
        #region SERVER CALLBACKS
        public override void OnServerReady(NetworkConnection conn)
        {
            LogInfo.theLogger.Log("Server ready");
    
            base.OnServerReady(conn);
        }
    
        public override void OnStartServer()
        {
            LogInfo.theLogger.Log("Server start");
    
            base.OnStartServer();
        }
    
        public override void OnServerConnect(NetworkConnection conn)
        {
            LogInfo.theLogger.Log("Server connect");
    
            base.OnServerConnect(conn);
        }
    
        public override void OnServerDisconnect(NetworkConnection conn)
        {
            LogInfo.theLogger.Log("Server disconnect");
    
            base.OnServerDisconnect(conn);
        }
    
        public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
        {
            LogInfo.theLogger.Log("Server add player");
    
            base.OnServerAddPlayer(conn, playerControllerId);
        }
    
        public override void OnServerRemovePlayer(NetworkConnection conn, PlayerController player)
        {
            LogInfo.theLogger.Log("Server remove player");
    
            base.OnServerRemovePlayer(conn, player);
        }
    
        public override void OnServerError(NetworkConnection conn, int errorCode)
        {
            LogInfo.theLogger.Log("Server error");
    
            base.OnServerError(conn, errorCode);
        }
    
        public override void OnStartHost()
        {
            LogInfo.theLogger.Log("Host start");
    
            base.OnStartHost();
        }
    
        public override void OnStopHost()
        {
            LogInfo.theLogger.Log("Host stop");
    
            base.OnStopHost();
        }
    
        public override void OnStopServer()
        {
            LogInfo.theLogger.Log("Server stop");
    
            base.OnStopServer();
        }
        #endregion
    
        #region CLIENT CALLBACKS
        public override void OnClientConnect(NetworkConnection conn)
        {
            LogInfo.theLogger.Log("Client connect");
    
            base.OnClientConnect(conn);
        }
    
        public override void OnClientDisconnect(NetworkConnection conn)
        {
            LogInfo.theLogger.Log("Client disconnect");
    
            base.OnClientDisconnect(conn);
        }
    
        public override void OnClientError(NetworkConnection conn, int errorCode)
        {
            LogInfo.theLogger.Log("Client error");
    
            base.OnClientError(conn, errorCode);
        }
    
        public override void OnStartClient(NetworkClient client)
        {
            LogInfo.theLogger.Log("Client start");
    
            base.OnStartClient(client);
        }
    
        public override void OnStopClient()
        {
            LogInfo.theLogger.Log("Client stop");
    
            base.OnStopClient();
        }
        #endregion
    
        #region MATCHMAKER CALLBACKS
        public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
        {
            LogInfo.theLogger.Log("Match create");
    
            //MatchCreate结束后进行OnMatchCreate回调,而在base中OnMatchCreate时会
            //立马创建host(即创建一个server和client),所以当重复创建match时报错
            //为避免此类问题可以在OnMatchCreate中不调用base的OnMatchCreate,通过自行创建List<MatchInfoSnapshot>变量自己存储比赛(matches)
            //然后在需要创建host时,再startHost,但是一般游戏时只允许玩家创建一个游戏,创建另一个游戏时需退出当前游戏
            base.OnMatchCreate(success, extendedInfo, matchInfo);
            matchMaker.ListMatches(0, 5, "", true, 0, 0, OnMatchList);
        }
    
        public override void OnMatchJoined(bool success, string extendedInfo, MatchInfo matchInfo)
        {
            LogInfo.theLogger.Log("Match joint");
    
            base.OnMatchJoined(success, extendedInfo, matchInfo);
        }
    
        public override void OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matchList)
        {
            LogInfo.theLogger.Log("Match list:"+ matchList.Count);//基函数的OnMatchList把matchList赋值给matches,此处matches仍为初始值
    
            base.OnMatchList(success, extendedInfo, matchList);
    
            if(ListMatchAction!=null)
            {
                ListMatchAction(matchList);
            }
            //LogInfo.theLogger.Log("Match list:" + matches.Count);
        }
        #endregion
    
        #region CONTROLL METHODS
        /// <summary>
        /// UI调用,开启server
        /// </summary>
        public void StartServer_()
        {
            if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
            {
                StartServer();
            }
        }
    
        /// <summary>
        /// UI调用,开启Host
        /// </summary>
        public void StartHost_()
        {
            if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
            {
                StartHost();
            }
        }
    
        /// <summary>
        /// UI调用,开启client
        /// </summary>
        public void StartClient_()
        {
            if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
            {
                StartClient();
            }
        }
    
        /// <summary>
        /// UI调用,MatchMaker
        /// </summary>
        public void StartMatchMaker_()
        {
            if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
            {
                StartMatchMaker();
                matchMode = true;
            }
        }
    
        /// <summary>
        /// UI调用,停止服务
        /// </summary>
        public void StopAllService()
        {
            if (NetworkServer.active || IsClientConnected())
            {
                StopHost();
            }
    
            if (client != null && NetworkClient.active)
            {
                StopClient();
            }
    
            if (matchMaker != null)
            {
                StopMatchMaker();
                matchMode = false;
            }
        }
    
        /// <summary>
        /// UI调用,创建比赛
        /// </summary>
        public void CreateMatch_()
        {
            if (matchMaker != null)
            {
                matchMaker.CreateMatch("LLMatch", 3, true, "", "", "", 0, 0, OnMatchCreate);
            }
        }
        /// <summary>
        /// 加入指定的比赛
        /// 对于建立比赛的player,本身已经在游戏中,所以不能再次加入(已经生成host)
        /// 对于建立比赛的player,在加入其他游戏时先取消比赛(DestroyMatch)
        /// 对于加入比赛的player,只能加入一次,不能重复加入(已经生成client)
        /// 对于加入比赛的Player,在重复加入或者加入其他游戏之前先断开连接(DropConnection)
        /// 本程序为demo,上述问题不做处理
        /// </summary>
        /// <param name="jointMatch"></param>
        public void JoinMatch(MatchInfoSnapshot jointMatch)
        {
            if (matchMaker == null) StartMatchMaker();
    
            matchMaker.JoinMatch(jointMatch.networkId, "", "", "", 0, 0, OnMatchJoined);//调用此方法时生成client
        }
        #endregion
    
        private void Update()
        {
            //取消了实时更新列表,可以测试使用
            //if(Time.time>refreshTime && matchMode)
            //{
            //    if (matchMaker == null) StartMatchMaker();
    
            //    matchMaker.ListMatches(0, 5, "", true, 0, 0, OnMatchList);
    
            //    refreshTime += 4;
            //}        
        }
    }
    using System;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Networking;
    using UnityEngine.Networking.Match;
    using UnityEngine.UI;
    
    public class CustomerUnetMainMenu : MonoBehaviour
    {
        public Button serverButton;
        public Button hostButton;
        public Button clinetButton;
        public Button matchMakerButton;
        public Button stopButton;
        public Button createMatchButton;
    
        public GameObject starts;
        public GameObject matches;
        public CustomerUnetManger theManager;
        public MatchListRefresher refresher;
    
        private bool matchCreated = false;
    
        #region BUTTON METHODS
    
        private void StartServer()
        {
            theManager.StartServer_();
        }
    
        private void StartHost()
        {
            theManager.StartHost_();
        }
    
        private void StartClient()
        {
            theManager.StartClient_();
        }
    
        private void StartMatchMaker()
        {
            theManager.StartMatchMaker_();
    
            matches.SetActive(true);
            starts.SetActive(false);
        }
    
        private void Stop()
        {
            theManager.StopAllService();
    
            matches.SetActive(false);
            starts.SetActive(true);
            matchCreated = false;
        }
    
        private void CreateMatch()
        {
            if(!matchCreated)
            {
                theManager.CreateMatch_();
                matchCreated = true;
            }
        }
    
        #endregion
    
        private void Start()
        {
            serverButton.onClick.AddListener(StartServer);
            hostButton.onClick.AddListener(StartHost);
            clinetButton.onClick.AddListener(StartClient);
            matchMakerButton.onClick.AddListener(StartMatchMaker);
            stopButton.onClick.AddListener(Stop);
            createMatchButton.onClick.AddListener(CreateMatch);
    
            theManager.ListMatchAction += OnListMatch;
        }
    
        private void OnListMatch(List<MatchInfoSnapshot> list)
        {
            refresher.RefreshList(list);
        }
    }
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Networking.Match;
    
    public class MatchListRefresher : MonoBehaviour
    {
        [SerializeField]
        private GameObject matchButton;
    
        //直接清除列表的刷新的方式不好,可通过一下两种方法解决:
        //1、增加本地存储matches,针对每次反馈的matches比对,只实例化增加或者销毁不存在的
        //2、或者每次增加或者减少比赛,可以尝试让服务端调用每个客户端执行
        public void RefreshList(List<MatchInfoSnapshot> matches)
        {
            ClearList();
    
            foreach(var match in matches)
            {
                var button = Instantiate(matchButton, transform);
                button.GetComponent<MatchButton>().Initialize(match);
            }
        }
    
        private void ClearList()
        {
            foreach(Transform t in transform)
            {
                Destroy(t.gameObject);
            }
        }
    }
    using UnityEngine;
    using UnityEngine.Networking;
    using UnityEngine.Networking.Match;
    using UnityEngine.UI;
    
    public class MatchButton : MonoBehaviour
    {
        private MatchInfoSnapshot match;
        //private NetworkManager manager;
    
        public void Initialize(MatchInfoSnapshot match)
        {
            this.match = match;
    
            GetComponentInChildren<Text>().text = match.name;
            GetComponent<Button>().onClick.AddListener(() =>
            {
                //manager.matchMaker.JoinMatch(match);
                FindObjectOfType<CustomerUnetManger>().JoinMatch(match);
            });
        }
    }
    using UnityEngine;
    using UnityEngine.UI;
    
    public class LogInfo : MonoBehaviour
    {
        public bool isDebug = true;
        private Text log;
    
        public static LogInfo theLogger;
    
        public void Log(string info)
        {
            if(isDebug)
            log.text += "
    " + info;
        }
    
        private void Clear()
        {
            log.text = "Log:";
        }
    
        void Start ()
        {
            theLogger = this;
            log = GetComponent<Text>();
            log.text = "Log:";
            GetComponentInChildren<Button>().onClick.AddListener(Clear);
        }
    
    }
  • 相关阅读:
    InPut 标签 HTML(表单)
    JavaScript Table 对象
    JCBD
    JCBD
    JavaScript prototype 属性
    Java8 新特性
    JavaScript 对象的使用
    Java 反射
    虚拟机VirtualBox启动虚拟机报Only Ethernet Adapter' (VERR_INTNET_FLT_IF_NOT_FOUND).
    Impala 数值函数
  • 原文地址:https://www.cnblogs.com/llstart-new0201/p/9280444.html
Copyright © 2011-2022 走看看