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) 消息处理委托函数