Move/Carry 非根游戏对象到另一个场景

Move/Carry non root GameObject to another Scene

我在将两个游戏对象实例化到一个场景中时遇到问题,我已将这两个游戏对象存储在前一个场景的两个变量中。我正在调试以确保变量确实填充了必要的游戏对象,而且确实如此。但是当我尝试将这些游戏对象实例化到新场景中时,出现错误:

ArgumentException: The Object you want to instantiate is null.
UnityEngine.Object.CheckNullArgument (System.Object arg, System.String message) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:238)
UnityEngine.Object.Instantiate (UnityEngine.Object original, Vector3 position, Quaternion rotation) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:150)
UnityEngine.Object.Instantiate[GameObject] (UnityEngine.GameObject original, Vector3 position, Quaternion rotation) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:205)
GameManager.LoadAnimalAvatar () (at Assets/_Coloring_Book/__Scripts/GameManager.cs:84)
AvatarFinalPreview.Start () (at Assets/_Coloring_Book/__Scripts/ColoringBook/AvatarFinalPreview.cs:9)

我将游戏对象分配给一个对象中的变量,该对象通过在调用 StoreAnimalAvatar 的第一个场景中单击按钮从一个场景持续到另一个场景(不破坏),然后当我切换到下一个场景时,我有一个在其 Start 函数中调用 LoadAnimalAvatar 的脚本 (AvatarFinalPreview.cs)。我不确定为什么在我的调试日志中显示对象存在时它说对象为空。我做错了什么?

public void StoreAnimalAvatar()
    {
        GameObject uiObject3D = GameObject.Find("UIObject3D");
        GameObject animalToStore = GameObject.FindGameObjectWithTag("Avatar Preview");

        AnimalUIObject3D = uiObject3D;
        AnimalAvatar = animalToStore;

        Debug.Log("Animal Stored");
        Debug.Log(AnimalUIObject3D.name);
        Debug.Log(AnimalAvatar.name);
    }

    public void LoadAnimalAvatar()
    {
        GameObject canvas = GameObject.FindGameObjectWithTag("Canvas");

        GameObject uiObject3D = Instantiate(AnimalUIObject3D, new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
        GameObject avatar = Instantiate(AnimalAvatar, new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
        avatar.transform.SetParent(canvas.transform);
    }

When I've tried to use DontDestryOnLoad I get the error DontDestroyOnLoad only work for root GameObjects or components on root GameObjects. Is there another way to do this using your suggestion?

您有三个选择:

1。将该子对象的父对象设置为 null,然后对其调用 DontDestroyOnLoad。这将使该对象不再有父对象,以便 DontDestroyOnLoad 将对其起作用:

public GameObject yourChildObj;

....

yourChildObj.transform.parent = null;
DontDestroyOnLoad(yourChildObj);

2。对该对象的根调用 DontDestroyOnLoad。请注意,这将使根对象及其子对象存活。之后您必须手动销毁其他子对象和父对象,因为您只需要那个子对象。

获取该子对象的根对象。获取该根对象下除该子对象之外的所有子对象并将它们存储在一个数组中。将该子对象的父对象设置为 null,然后对该子对象调用 DontDestroyOnLoad。现在,销毁存储的子项和父项。

public GameObject yourChildObj;
...
Transform root = yourChildObj.transform.root;
ClearChildren(root, yourChildObj.transform);

ClearChildren函数:

public void ClearChildren(Transform targetRoot, Transform exclude)
{
    Debug.Log(targetRoot.childCount);
    int i = 0;

    //Array to hold all child obj
    GameObject[] allChildren = new GameObject[targetRoot.childCount];

    //Find all child obj and store to that array
    foreach (Transform child in targetRoot)
    {
        if (child != exclude)
        {
            allChildren[i] = child.gameObject;
            i += 1;
        }
    }

    //Remove exclude as the child
    exclude.parent = null;
    DontDestroyOnLoad(exclude);

    //Now destroy them
    foreach (GameObject child in allChildren)
    {
        if (child != null)
            DestroyImmediate(child.gameObject);
    }

    //Now destroy the parent
    if (targetRoot != null)
        DestroyImmediate(targetRoot);
}

3。使用SceneManager.GetSceneByName将该对象移动到另一个已加载的场景。

Scene yourNexScene = SceneManager.GetSceneByName("SceneName");
SceneManager.MoveGameObjectToScene(yourChildObj, yourNexScene);

我更喜欢选项1但是如果你需要在同一个根目录中有更多的对象离开然后选项2给你机会做那。