C# UNET:自动托管服务器或作为客户端加入
我试图避免手动确定正在运行的unity游戏的当前实例是主机还是客户端。有没有办法检测现有的游戏,如果有人加入游戏,如果没有人启动主机 请注意,玩家不知道网络内容,因此我不能期望他们启动自己的主机或选择现有主机进行连接 我使用C# UNET:自动托管服务器或作为客户端加入,c#,unity3d,networking,unity5,C#,Unity3d,Networking,Unity5,我试图避免手动确定正在运行的unity游戏的当前实例是主机还是客户端。有没有办法检测现有的游戏,如果有人加入游戏,如果没有人启动主机 请注意,玩家不知道网络内容,因此我不能期望他们启动自己的主机或选择现有主机进行连接 我使用NetworkDiscovery组件进行了如下尝试: public class TestPlayerSetup : NetworkDiscovery { private float timeToWait = 1f; private float timeWaited
NetworkDiscovery
组件进行了如下尝试:
public class TestPlayerSetup : NetworkDiscovery {
private float timeToWait = 1f;
private float timeWaited = 0f;
private bool hostDiscovered = false;
void Start () {
NetworkManager.singleton.networkAddress = "localhost";
NetworkManager.singleton.networkPort = 7777;
Initialize ();
StartAsClient ();
}
void Update() {
if (timeWaited < timeToWait) {
timeWaited += Time.deltaTime;
return;
}
if (!hostDiscovered) {
NetworkServer.Reset ();
NetworkManager.singleton.StartHost ();
StartAsServer ();
hostDiscovered = true;
}
}
public override void OnReceivedBroadcast(string fromAddress, string data){
Debug.Log ("received broadcast");
NetworkManager.singleton.StartClient();
hostDiscovered = true;
setPlayerColor ();
}
}
公共类TestPlayerSetup:NetworkDiscovery{
专用浮动时间等待=1f;
私有浮动时间等待=0f;
private bool hostDiscovered=false;
无效开始(){
NetworkManager.singleton.networkAddress=“localhost”;
NetworkManager.singleton.networkPort=7777;
初始化();
StartAsClient();
}
无效更新(){
if(timewait
但在启动客户端之后,似乎无法启动NetworkDiscovery
服务器
上面的代码返回该错误(StartAServer失败,因为 已经有一个客户端正在运行) 删除
NetworkManager.singleton.StartClient()从接收广播功能中的功能。这是指每次调用OnReceivedBroadcast
时尝试启动客户端
至于自动连接到服务器,请不要这样做。相反,向玩家显示可用服务器的列表,他们的工作就是选择一个。将代码分为服务器代码和客户端代码
首先,在OnReceivedBroadcast
函数中忽略字符串fromAddress
参数。不要用那个
在服务器上执行的操作:
在服务器代码上,创建一个简单的类来保存服务器的ip和端口号。使用Unity序列化类并将其保存到NetworkDiscovery.broadcastData
。现在可以调用StartAsServer()代码>
在客户端执行的操作:
创建一个列表
,该列表包含包含服务器ip和端口的类。使用(字符串数据
)作为第二个参数,在OnReceivedBroadcast
函数中填充此列表
。因为它是一个字符串,所以必须使用将其转换回类。仅当ip和端口不在列表中时,才将其添加到列表中
就这样。然后,玩家可以从包含服务器ip和端口的列表中选择要连接到的服务器
上面的代码返回该错误(StartAServer失败,因为
已经有一个客户端正在运行)
删除NetworkManager.singleton.StartClient()从接收广播功能中的功能。这是指每次调用OnReceivedBroadcast
时尝试启动客户端
至于自动连接到服务器,请不要这样做。相反,向玩家显示可用服务器的列表,他们的工作就是选择一个。将代码分为服务器代码和客户端代码
首先,在OnReceivedBroadcast
函数中忽略字符串fromAddress
参数。不要用那个
在服务器上执行的操作:
在服务器代码上,创建一个简单的类来保存服务器的ip和端口号。使用Unity序列化类并将其保存到NetworkDiscovery.broadcastData
。现在可以调用StartAsServer()代码>
在客户端执行的操作:
创建一个列表
,该列表包含包含服务器ip和端口的类。使用(字符串数据
)作为第二个参数,在OnReceivedBroadcast
函数中填充此列表
。因为它是一个字符串,所以必须使用将其转换回类。仅当ip和端口不在列表中时,才将其添加到列表中
就这样。然后,玩家可以从包含服务器ip和端口的列表中选择要连接到的服务器。当作为客户端运行时未发现主机时,我通过删除网络发现组件并添加一个新组件来启动主机,从而使其正常工作:
private float timeToWait = 1f;
private float timeWaited = 0f;
private NetworkDiscovery serverNetwork;
private TestPlayerClient clientNetwork;
private bool serverStarted = false;
private bool hostDiscovered = false;
void Start () {
NetworkManager.singleton.networkAddress = "localhost";
NetworkManager.singleton.networkPort = 7777;
clientNetwork = gameObject.AddComponent<TestPlayerClient> ();
}
void Update() {
if (timeWaited < timeToWait) {
timeWaited += Time.deltaTime;
return;
}
hostDiscovered = clientNetwork.hostDiscovered;
if(clientNetwork != null && !hostDiscovered) {
clientNetwork.StopBroadcast ();
Destroy (clientNetwork);
return;
}
if (!hostDiscovered && !serverStarted) {
NetworkManager.singleton.StartHost ();
serverNetwork = gameObject.AddComponent<NetworkDiscovery> ();
serverNetwork.Initialize ();
serverNetwork.StartAsServer ();
serverStarted = true;
}
}
当作为客户机运行时未发现主机时,我删除了NetworkDiscovery
组件,并添加了一个新组件以启动主机,从而使其正常工作:
private float timeToWait = 1f;
private float timeWaited = 0f;
private NetworkDiscovery serverNetwork;
private TestPlayerClient clientNetwork;
private bool serverStarted = false;
private bool hostDiscovered = false;
void Start () {
NetworkManager.singleton.networkAddress = "localhost";
NetworkManager.singleton.networkPort = 7777;
clientNetwork = gameObject.AddComponent<TestPlayerClient> ();
}
void Update() {
if (timeWaited < timeToWait) {
timeWaited += Time.deltaTime;
return;
}
hostDiscovered = clientNetwork.hostDiscovered;
if(clientNetwork != null && !hostDiscovered) {
clientNetwork.StopBroadcast ();
Destroy (clientNetwork);
return;
}
if (!hostDiscovered && !serverStarted) {
NetworkManager.singleton.StartHost ();
serverNetwork = gameObject.AddComponent<NetworkDiscovery> ();
serverNetwork.Initialize ();
serverNetwork.StartAsServer ();
serverStarted = true;
}
}
如果NetworkDiscovery
的可能重复项不起作用,请使用UDP实现您自己的。请参阅重复的问题。@Programmer没有办法让NetworkDiscovery
这样做吗?对于一个简单的问题,UDP似乎是一个非常复杂的解决方案。“但是,在启动客户端之后,您似乎无法启动NetworkDiscovery
服务器。”您认为这是为什么?上面的代码返回该错误(StartAsServer
失败,因为已经有客户端在运行)如果NetworkDiscovery
的可能重复项不起作用,请使用UDP实现您自己的。请参阅重复的问题。@Programmer没有办法让NetworkDiscovery
这样做吗?对于一个简单的问题,UDP似乎是一个非常复杂的解决方案。“但是,在启动客户端之后,您似乎无法启动NetworkDiscovery
服务器。”您认为这是为什么?上面的代码返回该错误(StartAsServer
失败,因为已经有客户端在运行)其目的正是为了自动承载和连接,所以我不能忽视这一点。当然,请继续。制作一个自动连接到服务器的游戏。如果同一网络上有两台服务器,则自动连接到一台服务器,即使是i