0
votes

I have a GameObject that I am spawning from a pool, that when I try to return it to the pool I get the error:

Setting the parent of a transform which resides in a prefab is disabled to prevent data corruption.

I have used my ObjectPooler in many projects and have never once encountered this error.

I have created simple test GameObjects and it still throws this error, using the below code.

I have a Bomb abstract class. I have a PowerBomb class that inherits from Bomb. Bomb conforms to an interface IExplodable.

When my player spawns a bomb, I put it as the child of the player object so the player can move around with the bomb.

My ObjectPool has the correct bomb gameobject prefab ( a PowerBomb ). and my player has the same prefab as a reference to spawn. They player also holds a reference so it knows what it is holding.

I have spent the better part of 2 days trying to figure out why my PowerBomb will not return to the object pool.

Any help?

Bomb.cs

public abstract class Bomb : MonoBehaviour, IExplodable {

    //Interface
    public virtual void OnDetonate() {
        Die();
    }

    public virtual void Die() {
        Debug.Log("Bomb Die()");
        ObjectPool.instance.PoolObject(gameObject);
    }
}

PowerBomb.cs

public class PowerBomb : Bomb {
    [SerializeField]
    private AudioClip sfxSpawn;
}

BombManager.cs

public GameObject bomb;

public void SpawnBomb(){
    GameObject obj = ObjectPool.instance.GetObject(bomb);
    if (obj == null) return;
    obj.SetActive(true);
    PlayerInstance.HoldObject(obj);
}


public void DetonateBomb(){
    bomb.GetComponent<PowerBomb>().OnDetonate();
}

Player.cs

[SerializeField]
private bool isHolding = false;
public bool IsHolding {
    get { return isHolding; }
    set { isHolding = value; }
}

private GameObject holdingObject;
public GameObject HoldingObject {
    get { return holdingObject; }
    set { holdingObject = value;}
}

public void HoldObject(GameObject o) {
    HoldingObject = o;
    HoldingObject.transform.SetParent(transform);
    HoldingObject.transform.position = holdingArea.transform.position;
    IsHolding = true;
}

ObjectPool.cs

private GameObject containerObject;
private List<GameObject>[] pooledObjects;


//Code removed for brevity. Getting from the pool is fine.    


public void PoolObject(GameObject obj) {
    for (int i = 0; i < objectsToPool.Count; i++) {
        if (objectsToPool[i].objectToPool.name.Equals(obj.name)) {
            obj.SetActive(false);

//THIS LINE IS THROWING THE ERROR
            obj.transform.SetParent(containerObject.transform); 

            pooledObjects[i].Add(obj);
            return;
        }
    }
}
1
What are you trying to accomplish with obj.transform.SetParent(containerObject.transform);?Programmer
That keeps all my prefabs under one GameObject for tidiness.user-44651

1 Answers

2
votes

You don't and can't modify a prefab. It might work in the Editor if you use some Editor API to modify it but it won't during run-time and it won't change the changes. You are getting this error because obj is a prefab which you are trying to modify at obj.transform.SetParent(containerObject.transform);.

You don't even use prefabs in a pool. That's not normal. What you do do is use the Instantiate function to instantiate the prefab then put the instantiated object in a pool.

GameObject obj =  Instantiate(prefab, new Vector3(i * 2.0F, 0, 0), Quaternion.identity);

//Add instantiated Object to your pool List
pooledObjects[i].Add(obj);