Unity3d局域网PVP系统

Unity3d局域网PVP系统主要用来实现局域网对战功能,玩家可以建立自己的主机,其他玩家可以访问到该主机并使用RPC进行数据传输。

建立LANPVPMng.cs脚本来实现以下功能:

1、玩家建立局域网主机;

2、玩家搜索局域网其他玩家建立的主机;

3、玩家与玩家建立连接,进行数据传递。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class LANPVPMng : MonoBehaviour
{

    /// <summary>
    /// 最大连接数,默认为1
    /// </summary>
    public int MaxConnetions = 1;

    /// <summary>
    /// 端口号,默认为25002
    /// </summary>
    public int Port = 25002;

    /// <summary>
    /// 接受的数据
    /// </summary>
    public byte[] RecievedMsg
    {
        get
        {
            return m_recvMsg;
        }
    }

    /// <summary>
    /// 新消息事件
    /// </summary>
    public event NewMessageHandle NewMsgEvent;

    private byte[] m_recvMsg = new byte[0];
    Dictionary<string, HostData> m_host = new Dictionary<string, HostData>();
    List<string> m_hostName = new List<string>();
    HostData m_connectedHost = null;
    bool m_isfresh = true;
    bool m_isConnected = false;

    void Awake()
    {
        gameObject.AddComponent<NetworkView>();
    }

    void LateUpdate()
    {
        if (MasterServer.PollHostList().Length != 0 && m_isfresh == true)
        {
            HostData[] hostData = MasterServer.PollHostList();
            m_hostName.Clear();
            m_host = new Dictionary<string, HostData>();

            foreach (HostData h in hostData)
            {
                if (h.connectedPlayers == 1)
                {
                    m_host.Add(h.gameName, h);
                    m_hostName.Add(h.gameName);
                }
            }
            m_isfresh = false;
        }
    }

    //从列表中清除已经连接的主机
    //void FixedUpdate()
    //{
    //    //只有在没连接的时候才更新
    //    if (!m_isConnected)
    //    {
    //        for (int i = 0; i < m_hostName.Count; )
    //        {
    //            if (m_host[m_hostName[i]].connectedPlayers > 1)
    //            {
    //                m_host.Remove(m_hostName[i]);
    //                m_hostName.Remove(m_hostName[i]);
    //            }
    //            else
    //            {
    //                i++;
    //            }
    //        }
    //    }
    //}

    /// <summary>
    /// 创建主机
    /// </summary>
    /// <param name="hostName">创建的主机名</param>
    public bool CreateHostWithName(string hostName)
    {
        if (Network.peerType == NetworkPeerType.Server)
        {
            Disconnect();
        }

        if (Network.peerType == NetworkPeerType.Disconnected)
        {
            bool useNat = !Network.HavePublicAddress();
            Network.InitializeServer(MaxConnetions, Port, useNat);
            MasterServer.RegisterHost("battle", hostName, "");
            return true;
        }
        return false;
    }
  
    /// <summary>
    /// 刷新主机列表
    /// </summary>
    public void Refresh()
    {
        MasterServer.ClearHostList();
        MasterServer.RequestHostList("battle");
        m_host = null;
        m_isfresh = true;

    }

    /// <summary>
    /// 获得主机名序列,如果要获得最新的,需要调用ReFresh函数刷新
    /// </summary>
    public List<string> GetHostName()
    {
        return m_hostName;
    }

    /// <summary>
    /// 连接主机
    /// </summary>
    /// <param name="hostName">要连接的主机名</param>
    public void ConnectToHost(string hostName)
    {
        if (m_host.ContainsKey(hostName) && m_host[hostName].connectedPlayers == 1)
        {
            Network.Connect(m_host[hostName]);
            m_connectedHost = m_host[hostName];
            m_isConnected = true;
        }
    }

    /// <summary>
    /// 断线重连
    /// </summary>
    public void ReConnectToLastHost()
    {
        if (m_connectedHost != null)
        {
            Network.Connect(m_connectedHost);
        }
    }

    /// <summary>
    /// 发送数据
    /// </summary>
    /// <param name="msg">byte数组</param>
    public void SendData(byte[] data)
    {
        networkView.RPC("SomeoneSay", RPCMode.Others, data);
    }

    /// <summary>
    /// 断开连接
    /// </summary>
    public void Disconnect()
    {
        Network.Disconnect(200);
        m_isConnected = false;
    }

    /// <summary>
    /// 判断是否连接到其他主机
    /// </summary>
    public bool IsConnected()
    {
        if (Network.isClient||Network.isServer)
        {
            return true;
        }
        return false;
    }

    /// <summary>
    /// 新消息事件委托函数
    /// </summary>
    /// <param name="msg"></param>
    public delegate void NewMessageHandle(byte[] msg);

    //RPC function to receive your message!
    [RPC]
    void SomeoneSay(byte[] data, NetworkMessageInfo info)
    {
        m_recvMsg = data;
        NewMsgEvent(m_recvMsg);
    }
}

Awake()函数将绑定端口监听组件,注意:

1、玩家建立的主机名必须唯一,主机名以参数形式传入,可使用玩家ID或玩家IP地址等等;
2、每个主机只允许一个玩家连入;
3、搜索局域网主机时,要及时调用Refresh()函数,否则无法显示最新主机列表;
4、LANPVPMng.RecievedMsg只保留最新传递的数据,目前没有提供历史记录功能。RPC接收到新的消息时,会触发事件NewMsgEvent,上层可通过加载NewMsgEvent事件来获得及时消息更新。

成员变量与成员函数说明列表:

成员变量:
public int MaxConnetions = 1; 主机最大连接数,默认为1,只允许一个其他玩家连接
public int Port = 25002; 端口号,默认为25002
public byte[] RecievedMsg; 接收到的数据,只读
public bool IsConnected 是否连接到其他主机
public event NewMessageHandle NewMsgEvent; 消息事件,每次RPC函数调用时触发

成员函数:
public bool CreateHostWithName(string hostName) 创建主机
public void Refresh() 刷新主机列表
public List<string> GetHostName() 获得主机名序列
public void ConnectToHost(string hostName) 连接到主机
public void ReConnectToLastHost() 断线重连
public void SendData(byte[] data) 发送数据
public void Disconnect() 断开连接
public bool IsConnected() 是否连接到其他主机
public delegate void NewMessageHandle(byte[] msg) 消息处理委托函数


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值