我正在使用Unity3D网络开展网络游戏。我是网络编程的新手。
假设我创建了对象并将它们附加到播放器(在服务器或客户端上)。我需要继续在另一台设备上显示这些对象。我见过很多材料,但我还没有找到解决方案。
看来NetworkServer.Spawn是一种方法。这是正确的,还有其他更好的方法吗?给这个新手一些建议^^谢谢。
答案 0 :(得分:0)
如果您正在使用NetworkServer.Spawn,则需要在NetworkManager中注册预制件。
如果您不希望任何新人加入您的服务器,您也可以使用Command和ClientRPC生成此预制件并将其设为父级,以纠正每个客户端上的游戏对象。
答案 1 :(得分:0)
只有服务器/主机才能生成网络同步的GameObjects。
// put this component on a prefab you wish to spawn
class MyNetworkedObject : NetworkBehaviour
{
[SyncVar]
public int myHealth;
void Start()
{
Debug.Log("My health is: " + myHealth);
}
}
// put this component on an empty GameObject somewhere in the scene and check "Server Only" on its NetworkIdentity
class MySpawner : NetworkBehaviour
{
public MyNetworkedObject myPrefab;
void OnValidate()
{
if (GetComponent<NetworkIdentity>().serverOnly == false)
Debug.LogWarning("This component wants NetworkIdentity to have \"Server Only\" checked (for educational purposes, not an actual requirement).");
}
public void SpawnObject(int withHealth)
{
if (!isServer)
throw new Exception("Only server may call this! It wouldn't have any effect on client.");
MyNetworkedObject newObject = Instantiate(myPrefab);
// setup newObject here, before you spawn it
newObject.myHealth = withHealth;
NetworkServer.Spawn(newObject.gameObject);
}
}
正如Fiffe已经提到的那样,预制件必须在NetworkManager中注册才能生成。此外,所有联网对象都必须具有NetworkIdentity组件。
一旦服务器生成了对象,服务器将告诉所有连接的客户端使用任何SyncVars的当前值以及稍后可能连接的任何客户端生成对象。如果SyncVars在服务器上发生更改,服务器将告知所有连接的客户端相应地更改值。
如果您希望客户端调用对象的产生,最简单的方法是使用Local Authority:
// put this component on the player prefab that you already assigned to NetworkManager.PlayerPrefab
class MyNetworkedPlayerObject : NetworkBehaviour
{
void OnValidate()
{
if (GetComponent<NetworkIdentity>().localPlayerAuthority == false)
Debug.LogWarning("This component requires NetworkIdentity to have \"Local Player Authority\" checked.");
}
public void RequestSpawnObject(int withHealth)
{
if (!hasAuthority)
throw new Exception("Only the player owned by this client may call me.");
// the following call will magically execute on the server, even though it was called on the client
CmdSpawnObject(withHealth);
}
[Command]
private void CmdSpawnObject(int withHealth)
{
// this code will always run on the server
FindObjectOfType<MySpawner>().SpawnObject(withHealth);
}
}
每个客户端都可以拥有一个或多个具有本地播放器权限的联网对象。每个联网对象或者由服务器拥有,或者由一个具有该对象的本地玩家权限的客户端拥有。客户端只能在该客户端具有本地播放器权限的对象上调用命令。命令由客户端调用,但在服务器上执行。此执行将异步发生,客户端无法知道服务器何时执行它。因此,命令可以有参数,但没有返回值。
此外:
[ClientRPC]
方法,然后在客户端上执行。如果客户端稍后连接,它将不调用在客户端连接之前发生的rpc调用。我希望这能给你一个简短的概述。