将非根游戏对象移动/携带到另一个场景

时间:2017-12-20 16:28:29

标签: c# unity3d instantiation

我无法将两个游戏对象实例化为一个场景,我将其存储在前一个场景中的两个变量中。我正在调试以确保变量确实填充了必要的Gameobject,它们是。但是当我尝试将这些Gameobject实例化为新场景时,我收到了错误:

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的场景中的按钮点击,然后当我切换到下一个场景时,我有一个脚本( AvatarFinalPreview.cs)在其Start函数中调用LoadAnimalAvatar。我不确定为什么在我的调试日志中它表示它们存在时,该对象为null。我做错了什么?

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);
    }

1 个答案:

答案 0 :(得分:2)

  

当我尝试使用DontDestryOnLoad时,我收到了错误消息   DontDestroyOnLoad仅适用于根游戏对象或root上的组件   GameObjects。是否有其他方法可以使用您的建议?

您有三种选择:

1 。将该子对象的父对象设置为null,然后在其上调用DontDestroyOnLoad。这将使对象不再具有父级,以便DontDestroyOnLoad可以使用它:

public GameObject yourChildObj;

....

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

2 .Call 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 就有机会这样做。