Unity 无法销毁克隆游戏对象

Unity cannot destroy clones GameObject

我将 Photon PUN 用于多人游戏,并在玩家进入时从预制件实例化 GameObjects (OtherCraft),并在他们离开时销毁它们 - 或者更确切地说,销毁不起作用。相关代码如下:

预制件在 Start() 中加载,并且有一个字典来保存对实例化的引用(其他工艺现在只是一个带有网格和脚本的立方体):

    OtherCraft
            otherCraftPrefab;

    Dictionary<int, OtherCraft>
            otherCrafts = new Dictionary<int, OtherCraft>();
    
    ....  //  the following in Start()

    GameObject
            tmp = (GameObject)Resources.Load("Prefabs/OtherCraft", typeof(GameObject));
    otherCraftPrefab = null;


    if (tmp == null)
        Debug.Log("Failed to load prefab for other craft");

    else
        otherCraftPrefab = tmp.GetComponent<OtherCraft>();

当 OnPlayerEnteredRoom(Player newPlayer) 通知新玩家时,将创建一个新工艺并将其添加到字典中:

    OtherCraft
            otherCraft = Instantiate(otherCraftPrefab, new Vector3(0,1,0), Quaternion.identity);

    otherCraft.setActorNumber(newPlayer.ActorNumber);
    otherCraft.setNickName(newPlayer.NickName);

    otherCrafts.Add(newPlayer.ActorNumber, otherCraft);
    Debug.Log("Other craft instantiated - " + otherCraft.getNickName() + ", ActorNumber=" + otherCraft.getActorNumber());

Debug.Log 行显示一切正常(Created craft - OtherCraft(Clone) (OtherCraft): nick2, ActorNumber=2),正确的 ActorNumber 等,它显示在游戏视图和层次结构中。

OnPlayerLeftRoom(Player exPlayer) 通知玩家离开时,它会引用字典中的条目并再次删除它:

    OtherCraft
            otherCraft = otherCrafts[exPlayer.ActorNumber];
    int     actorNumber = otherCraft.getActorNumber();
    string  nickName = otherCraft.getNickName();
    Debug.Log("Recovered craft - " + otherCraft.ToString() + ": " + nickName + ", ActorNumber=" + actorNumber);

    otherCrafts.Remove(actorNumber);
    Destroy(otherCraft);

除非它不存在,否则它仍然存在于游戏视图和层次结构中。 Debug.Log 行也显示错误信息 (Recovered craft - OtherCraft(Clone) (OtherCraft): , ActorNumber=0)。它从字典中得到了错误的东西。

看不出我做错了什么?

我想我已经解决了这个问题。 GameObject - OtherCraft - 有一个脚本,也叫 OtherCraft。实际存储在字典中(后来被删除和销毁)的是脚本的实例,而不是 GameObject.

很多 Unity 社区指导文档、视频等都暗示要保持名称相同——“创建一个 GameObject 'Fred',现在添加一个脚本到它,命名为 - 为什么不 - 'Fred'”。好吧,那样做会带来麻烦。很多时候这两者是可以互换的,而且您无论如何都想访问脚本。它们几乎可以互换,但似乎并非总是如此。反正不是这种情况。

我将其更改为 GameObjectOtherCraftGo,保持脚本为 OtherCraft。字典被改成存储GameObjects,需要的时候通过OtherCraft script = myOtherCraftGo.GetComponent<OtherCraft>().

访问脚本

问题解决了。无论如何,对我来说,这是一个有益的教训。