Unity3d 如何在Unity networking中的两个设备上显示新创建的对象?

Unity3d 如何在Unity networking中的两个设备上显示新创建的对象?,unity3d,networking,multiplayer,spawn,Unity3d,Networking,Multiplayer,Spawn,我正在用Unity3D网络制作一个网络游戏。我是网络编程新手 假设我创建了对象并将其附加到播放器(服务器或客户端)。我需要在另一台设备上继续显示这些对象。我看过很多资料,但还没有找到解决办法 看起来NetworkServer.Spawn是一种方法。是这样吗?还有其他更好的方法吗?给这个新手一些建议^^^谢谢。如果您使用的是NetworkServer.Spawn,您需要在NetworkManager中注册预置 如果您不希望任何新用户加入您的服务器,您也可以使用命令和ClientRPC生成此预置并将

我正在用Unity3D网络制作一个网络游戏。我是网络编程新手

假设我创建了对象并将其附加到播放器(服务器或客户端)。我需要在另一台设备上继续显示这些对象。我看过很多资料,但还没有找到解决办法


看起来NetworkServer.Spawn是一种方法。是这样吗?还有其他更好的方法吗?给这个新手一些建议^^^谢谢。

如果您使用的是NetworkServer.Spawn,您需要在NetworkManager中注册预置


如果您不希望任何新用户加入您的服务器,您也可以使用命令和ClientRPC生成此预置并将其作为父对象,以更正每个客户端上的游戏对象。

只有服务器/主机可以生成网络同步的游戏对象

// 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);
    }
}
//将此组件放在您希望生成的预置上
类MyNetworkedObject:NetworkBehavior
{
[同步变量]
公共卫生;
void Start()
{
Log(“我的健康状况为:“+myHealth”);
}
}
//将此组件放在场景中某个空游戏对象上,并在其网络标识上选中“仅服务器”
MySpawner类:网络行为
{
公共MyNetworkedObject MyPrefact;
void OnValidate()
{
if(GetComponent().serverOnly==false)
LogWarning(“此组件希望NetworkIdentity选中\“仅服务器\”(出于教育目的,而不是实际需要)。”;
}
公共void对象(int with health)
{
如果(!isServer)
抛出新异常(“只有服务器可以调用它!它不会对客户端产生任何影响。”);
MyNetworkedObject newObject=实例化(myPrefab);
//在生成新对象之前,在此处设置新对象
newObject.myHealth=withHealth;
NetworkServer.Spawn(newObject.gameObject);
}
}
正如Fiffe已经提到的,预制必须在NetworkManager中注册,才能生成。此外,所有联网对象必须具有NetworkIdentity组件

一旦服务器生成该对象,服务器将通知所有连接的客户端使用任何SyncVars的当前值生成该对象,并在以后可能连接的任何客户端上生成该对象。如果服务器上的SyncVars发生更改,服务器将通知所有连接的客户端相应地更改该值

如果希望客户端调用对象的生成,最简单的方法是使用本地授权:

// 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);
    }
}
//将此组件放在已分配给NetworkManager.PlayerPrefab的播放器预置上
类MyNetworkedPlayerObject:NetworkBehavior
{
void OnValidate()
{
如果(GetComponent().localPlayerAuthority==false)
LogWarning(“此组件需要NetworkIdentity检查“本地播放器授权”);
}
公共void RequestSpawnObject(int with Health)
{
如果(!hasAuthority)
抛出新的异常(“只有该客户拥有的玩家可以打电话给我。”);
//下面的调用将在服务器上神奇地执行,即使它是在客户端上调用的
CmdSpawnObject(withHealth);
}
[命令]
私有void对象(int with health)
{
//此代码将始终在服务器上运行
FindObjectOfType().SpawnObject(带运行状况);
}
}
每个客户端可以有一个或多个具有本地玩家权限的网络对象。每个网络对象要么由服务器拥有,要么完全由一个拥有该对象本地播放器权限的客户端拥有。客户端只能在客户端拥有本地播放器权限的对象上调用命令。命令由客户端调用,但在服务器上执行。此执行将异步进行,客户端无法知道服务器何时执行。因此,命令可以有参数,但没有返回值

此外:

  • 如果希望所有客户端在网络对象上执行方法,服务器可以在任何网络对象上调用
    [ClientRPC]
    方法,然后在客户端上执行。如果客户端稍后连接,它将而不是调用在客户端连接之前发生的rpc调用
  • 即使是拥有本地玩家权限的客户端也无法更改SyncVar。如果这样做,服务器和其他客户端将不会收到更改。只有服务器可以更改SyncVars并将其同步到客户端
  • 变换是一种特殊情况。对象可以具有NetworkTransform组件,该组件允许拥有的客户机(或服务器)控制该对象的位置和旋转,并将其同步到服务器和其他客户机。与NetworkAnimator相同
  • 如果您想在运行时决定服务器或客户机是否对某个对象拥有权限,则必须为这两种情况设置一个预置,一个选中“本地玩家权限”,另一个不选中。服务器永远不能是已选中“本地玩家权限”的对象的所有者(但主机上的本地客户端可以)
  • 客户端可以向服务器发送消息,反之亦然

我希望这能给你一个简短的概述。

我想我需要学习更多关于Command&ClientPRC的知识。网络真让我困惑。谢谢你的回复^^