unity3D网络基础学习(一)

2015年08月20日 14:48 0 点赞 0 评论 更新于 2017-05-09 17:38

最近我在进行一个小型的Unity3D(U3D)网络手游项目的开发。由于个人不习惯做笔记,所以打算通过博客的形式记录知识点,同时也为和我一样正在学习U3D的朋友们提供一个交流学习的平台。在此声明,如果文章中有错误的地方,还请大家多多指正;若有更简单的方法或扩展知识,也希望大家能相互分享学习。后续的内容可能还会穿插Unity的Editor类知识、网络资源的打包下载以及Shader的学习等。

网络编程重要概念

在学习网络编程之前,我们需要先了解几个重要的概念,否则后续的代码可能会难以理解。

1. Network.Player

Network.Player 用于获取本地 NetworkPlayer 实例,它是一个可以从网络定位玩家的数据结构。我们通过查看API可知其包含以下变量:

  • NetworkPlayer.ipAddress:可获取该玩家的IP地址。
  • NetworkPlayer.externalIP:可获取外网的IP地址。
  • portexternal port:分别用于获取端口和外网端口。内网和外网的区别,简单来说,内网是指局域网,外网则是外部网络,大家可以自行查阅更详细的资料。
  • GUID:在初始化服务器的参数中会用到,但具体功能后续再详细说明,对其运行机制感兴趣的朋友可以自行查阅相关资料。

2. OnServerInitialized()

当调用并完成 Network.InitializeServer 时,会在服务器上调用此函数。Network.InitializeServer(connections : int, listenPort : int, useNat : bool) 用于初始化服务器,下面介绍其参数:

  • connections:允许的入站连接或玩家的数量。
  • listenPort:要监听的端口。如果不清楚端口的概念,建议自行查阅相关资料。
  • useNat:用于设置NAT穿透功能。若希望服务器能够接受使用NAT穿透的连接,可将其设置为 true

3. OnPlayerConnected()

当一个新玩家成功连接到服务器时,会调用此函数。

4. OnSerializeNetworkView()

此函数用于自定义变量同步,后续会对该函数进行详细讲解。

5. OnPlayerDisconnected()

当一个玩家从服务器上断开连接时,会在服务器端调用此函数。同时,可使用 Network.RemoveRPCs(player) 移除所有属于该玩家ID的RPC函数,使用 Network.Destroy() 跨网络销毁该物体(包括本地和远端)。

6. OnDisconnectedFromServer()

当客户端失去连接或从服务器端断开时,会调用此函数。

7. Network.peerType

表示端类型的状态,共有四种状态:disconnected(未连接)、connecting(正在连接)、server(服务器)或 client(客户端)。NetworkPeerType 描述了由 Network.peerType 返回的网络接口端类型的状态。

8. Network.connections

该属性包含所有连接的玩家信息。

9. NetworkView

网络视图,用于定义在网络上同步的内容以及同步方式。Gameobject.networkView 是附属于游戏物体上的网络视图,可使用 networkView.RPC() 进行远程过程调用。

10. Network.Disconnect()

用于关闭所有开放的连接并关闭网络接口。

简单连接的实现

了解上述函数后,我们来实现一个简单的连接。以下是相关代码及解释:

// Use this for initialization
// 定义远程连接IP地址
private string remoteIP = "127.0.0.1";
// 定义远程的端口号
private int remotePort = 10000;
// 限制连接数量为15个用户
private int connectCount = 15;
// 是否启用网络地址转换器
private bool useNAT = false;

void OnGUI()
{
switch (Network.peerType)
{
case NetworkPeerType.Disconnected:
// 服务器未开启时,开启服务器
StartConnect();
break;
case NetworkPeerType.Server:
// 成功连接服务器
OnServer();
break;
case NetworkPeerType.Client:
break;
case NetworkPeerType.Connecting:
break;
}
}

上述代码中,OnGUI() 函数用于根据网络连接状态进行不同的处理,Network.peerType 用于判断网络的连接状态(是否连接,是客户端还是服务端)。

void StartConnect()
{
remoteIP = GUI.TextField(new Rect(10, 30, 100, 20), remoteIP);
if (GUI.Button(new Rect(10, 50, 100, 30), "创建服务器"))
{
Network.incomingPassword = "UnityNetwork";
NetworkConnectionError error = Network.InitializeServer(connectCount, remotePort, useNAT);
Debug.Log(error);
}
if (GUI.Button(new Rect(10, 85, 100, 30), "连接服务器"))
{
NetworkConnectionError error = Network.Connect(remoteIP, remotePort, "UnityNetwork");
Debug.Log(error);
}
}

StartConnect() 函数表示服务端的连接操作,提供了创建服务器和连接服务器的按钮。

void OnServer()
{
GUILayout.Label("  服务端创建成功。等待连接····");
// 得到的IP与端口
string ip = Network.player.ipAddress;
int port = Network.player.port;
GUILayout.Label("  ip地址:" + ip + ".\n  端口号码:" + port);
// 连接到服务器的所有客户端
int connectLength = Network.connections.Length;
// 遍历所有客户端并获取IP与端口号
for (int i = 0; i < connectLength; i++)
{
GUILayout.Label("  连接的IP:" + Network.connections[i].ipAddress);
GUILayout.Label("  连接的端口:" + Network.connections[i].port);
}
if (GUI.Button(new Rect(10, 140, 100, 30), "断开连接"))
{
// 从服务器上断开连接
Network.Disconnect(200);
}
}

OnServer() 函数用于显示服务端的相关信息,包括服务端的IP地址、端口号以及连接的客户端信息,同时提供断开连接的按钮。

/// <summary>
/// 当有新的用户连接进来时
/// </summary>
void OnPlayerConnected(NetworkPlayer player)
{
Debug.Log("新连接入客户端:" + player);
SendMessage("createPlayer", player);
// networkView.RPC("OnNetworkLoaded", RPCMode.Others, player);
}

/// <summary>
/// 当现有用户断线时
/// </summary>
void OnPlayerDisconnected(NetworkPlayer player)
{
Debug.Log("清除对象: " + player);
Network.RemoveRPCs(player);
Network.DestroyPlayerObjects(player);
}

/// <summary>
/// 当前脚本作为客户端时 成功连接到服务器时 调用当前方法
/// </summary>
void OnConnectedToServer()
{
Debug.Log("客户端成功连接上服务器了!!!");
}

以上三个函数分别处理新用户连接、用户断线以及客户端成功连接到服务器的情况。

注意事项

SendMessage("createPlayer", player); 这个信息发送无法执行,因为 “createPlayer” 方法在另一个脚本中。如果有朋友想要尝试运行此脚本,可将这个方法暂时注释掉。

至此,创建连接的脚本已经完成。下次将更新信息同步的功能。

作者信息

洞悉

洞悉

共发布了 515 篇文章