Setting the Parent of A Transform Error

I am having an issue trying to use a set of prefabs to set the parent of them to the canvas (they are text objects, so I want them to delete the previous text object and use the next text prefab). Whenever I press the next button, it gives me this error

Setting the parent of a transform which resides in a Prefab Asset is disabled to prevent data corruption (GameObject: ‘Question5 (TMP)(Clone)’).
UnityEngine.Transform:SetParent(Transform)
QuizManager:NextQuestion() (at Assets/Scripts/QuizManager.cs:75)
UnityEngine.EventSystems.EventSystem:Update()

I have looked up multiple ways to solve this, but I have not been able to find one that works for me. This is not the only problem I have encountered, the code I have also does not delete the previous question, although that might be because of how I link the object in the code. Here is all the code in question.

using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class QuizManager : MonoBehaviour
{

    public List<GameObject> answers;
    public List<GameObject> questions;
    public GameObject canvas;

    private int i = 1;
    private GameObject instantiatedQuestion;
    private List<GameObject> instantiatedAnswers;

    public void Start()
    {

        int j = 0;
        float x = 0f;
        float y = 0f;

        i = 1;

        GameObject uiObj = Instantiate(questions[0], new Vector2(450, 330), Quaternion.identity);
        uiObj.transform.parent = canvas.transform;
        instantiatedQuestion = uiObj;

        for(j = 0; j < answers.Capacity; j++)
        {

            Debug.Log($"j = {j}");

            if (j == 0)
            {
                x = 262.5f;
                y = 224f;
            } else if (j == 1)
            {
                x = 692.5f;
                y = 224f;
            } else if (j == 2)
            {
                x = 262.5f;
                y = 139f;
            } else if (j == 3)
            {
                x = 692.5f;
                y = 139f;
            }

            GameObject answerObj = Instantiate(answers[j], new Vector2(x, y), Quaternion.identity);
            answerObj.transform.parent = canvas.transform;
        }

    }

    /**
     * NextQuestion will load up the next question by deleting the last question object and instantiating
     * the next object into the UI element
     **/
    public void NextQuestion()
    {

        i++;

        if(i < questions.Capacity)
        {
            Destroy(instantiatedQuestion);
            GameObject uiObj = new GameObject("myClone");
            uiObj = Instantiate(questions[i], new Vector2(450, 330), Quaternion.identity);
            uiObj.transform.SetParent(canvas.transform);
            instantiatedQuestion = uiObj;
        }


    }

    public void GoBack(string back)
    {
        Debug.Log("Going Back");
        SceneManager.LoadScene(back);
    }

}

Any help that can be provided is greatly appreciated.

At first I thought the code looked fine but I think this line might be causing it to act weirdly:

GameObject uiObj = new GameObject("myClone");

Remove that and it should work fine hopefully. Oh and also put:

GameObject uiObj = Instantiate(questions[i], new Vector2(450, 330), Quaternion.identity);

Is canvas a prefab or is it an object in the scene?

When instantiating things in a UI hierarchy, do not use the version of Instantiate that takes a position and rotation.

Instead use the version that takes the source prefab and a Transform to set as parent.

If you do not do that, then when assigning a parent, do not simply assign the .parent property. Instead use the .SetParent() call with the optional second argument set to true, otherwise nothing you put in the hierarchy will be visible.

All that being said, the error you are getting is from setting a prefab’s parent. In the code as it stands now I don’t see you actually doing that, so I’m not sure how you’re getting that error.

1 Like

Canvas is an object within the scene. Should it be a prefab instead? If I do that, I might have to remove the objects already in the scene. If it would help, I can post a picture of the scene.

I tried what changing the instantiate to just have the object and the tranform parent, but it gives me a different error this time.

Cannot instantiate objects with a parent which is persistent. New object will be created without a parent.
UnityEngine.Object:Instantiate(GameObject, Transform)
QuizManager:NextQuestion() (at Assets/Scripts/QuizManager.cs:82)
UnityEngine.EventSystems.EventSystem:Update()

Does Unity just not like it when you try to add a child to an already existing object?

Maybe your prefab is bugged/set up weirdly. Try remaking it from scratch?

edit: I tried reproducing your code but I couldn’t make it return an error. So maybe it is the prefab after all.

If you have dragged a prefab into the public GameObject canvas; field that’s not gonna work.

Instead you want to put the one in the scene into that, or if you need to instantiate the canvas too, then do so and replace the prefab reference.

Might do that, probably nuke what I have now and remake it using a different method maybe.

I checked, the GameObject that I imported was an already created canvas, it already exists in the scene.

1 Like