首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UNET:正确注册动态对象

UNET:正确注册动态对象
EN

Stack Overflow用户
提问于 2017-10-25 02:00:48
回答 1查看 597关注 0票数 0

作为一个业余编程爱好者,我正在从事我的一个个人项目。我对这个项目的目标是让玩家建造和定制他们自己的飞船,然后加入一个公共服务器并与之战斗。

我得到的错误是这样的:

生成服务器对象assetId=000000000000000000000000000000e7 netId=3 netId=3失败

下面是它最相关的代码:

代码语言:javascript
复制
    public void LoadShip(Vector2 pos, string path = "save.xml",Ship oldship = null){
    Debug.Log ("Loading Ship!");
    ShipObject shipObj;
    if (oldship != null) {
        shipObj = oldship.shipObjectClass;
    } else {
        GameObject newShip = new GameObject ();
        shipObj = newShip.AddComponent<ShipObject> ();
        Rigidbody2D rb = newShip.AddComponent<Rigidbody2D> ();
        rb.gravityScale = 0;
        rb.drag = 0.1f;
        rb.angularDrag = 0.1f;
    }
    shipObj.PrepareForLoad ();
    XmlSerializer serializer = new XmlSerializer (typeof(Ship));
    FileStream reader = new FileStream (Path.Combine(Application.dataPath, path), FileMode.Open);
    if (shipObj.LoadShip ((Ship)serializer.Deserialize (reader))) {
        shipObj.gameObject.transform.position = pos;
        reader.Close ();
        //Give all the children rigidbodies, as they are loaded without them
        //by default for when physics are not needed.
        for (int i = 0; i < shipObj.transform.childCount; i++) {
            GameObject child = shipObj.transform.GetChild (i).gameObject;
            Rigidbody2D rb = child.AddComponent<Rigidbody2D> ();
            rb.gravityScale = 0;
            rb.drag = 0;
            rb.angularDrag = 0;
            rb.mass = 0;
            rb.isKinematic = true;
        }
        shipObj.name = shipObj.ship.shipName;
        Debug.LogError ("Ship name = " + shipObj.name);
        ClientScene.RegisterPrefab (shipObj.gameObject, NetworkHash128.Parse (shipObj.name));
        GameObject prefab;
        ClientScene.prefabs.TryGetValue (NetworkHash128.Parse (shipObj.name), out prefab);
        if (!prefab) {
            Debug.LogError ("Prefab not registered!");
            return;
        }
        if (shipObj.GetComponent<NetworkIdentity> () != null) {
            Cmd_SpawnShip (prefab);
        } else {
            Debug.LogError ("No network identity here!");
        }
    }
}

[Command]
public void Cmd_SpawnShip(GameObject ship){
    NetworkServer.Spawn (ship);
}

作为您所看到的内容的一种简化: Player使用所需的产卵位置调用LoadShip(),它装载的船的路径,以及可能是他们想要覆盖的现有船只。然后,它使用XML加载所有必要的数据,添加物理,并根据船名注册预制件,在任何情况下都应该是唯一的。

主ship对象及其所有子对象(如墙壁、枪支、控制台等)都被赋予NetworkIdentity组件,主ship也在LoadShip()中被赋予了一个NetworkTransform组件。

无论哪个客户端选择加载它,服务器或其他客户端都无法看到它,而是接收该错误。

在过去的三个小时里,我一直在试图修复这个for..Maybe。这是漫长的一天,我相信你会相信我,当我说,我搜索了谷歌和堆栈溢出精心寻找一个已经发布的答案,我的问题。最常见的问题是:简单地不注册预制件,在服务器上注册预制件,忘记给它一个assetID,没有在客户机上调用它。我很确定我已经避免了所有这些事情,请不要把我和团结教程联系起来。我向你保证,我已经读过好几遍了。

另外,如果我只在一个客户端托管一个游戏,并且在一艘船中产卵,那么预告片不会显示在网络管理器的“注册预制件”列表中,即使我已经在'Debug‘日志级别上找到了网络管理器,并且它告诉我它成功地注册了预告片。

这是所有相关的信息。我会感谢你提前给我时间,希望我犯的任何错误都不会太明显。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-06 06:54:02

激发出更多解决这个问题的动机。在花了几个小时努力地在互联网上寻找答案之后,尤里卡!我在我的代码中有两个误解:

  • RegisterClientPrefab()不会自动从GameObject中创建一个预制件供服务器使用。我不知道为什么我一开始就这么想,事后看来是很明显的。
  • 我以为当RegisterClientPrefab()被调用时,它所做的就是告诉服务器,‘嘿,你,我做了些什么。--去和大家分享吧!’但实际上,它只是告诉单个客户端在哪里查找特定的assetId。

我解决这些误解的方法是,我只给服务器一个字典,其中包含每个船只的assetID和一个序列化的byte[]数组,然后是一个RegisterSpawnHandler,它将导致正确地生成对象。我不确定这是最好的方式,如果有任何其他形式的编码比byte[]数组更容易/更快地发送网络,但它对我是有效的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46922768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档