I have bumped into this issue multiple times now, the code used to work fine earlier and I can’t seem to find out what is wrong.
In a scene I have two objects, a paddle object and a brick object.
The paddle object has the following code to spawn a ball from a prefab. This prefab is set in the Unity manager to a prefab of a sphere object and this code executes fine.
public class PaddleScript : MonoBehaviour
{
public GameObject ballPrefab;
GameObject attachedBall;
void Start(){
SpawnBall();
}
public void SpawnBall()
{
attachedBall = (GameObject)Instantiate(ballPrefab);
}
The ball prefab has a BallScript C# script attached to it, as well as the tag “Ball”. It has some properties and methods but the important part is this:
public class BallScript : MonoBehaviour
{
public AudioClip hit;
// Again, this hit is setup in Unity.
public void Die()
{
AudioSource.PlayClipAtPoint(hit, transform.position, 0.5f);
PaddleScript paddleScript = GameObject.Find("Paddle").GetComponent<PaddleScript>();
paddleScript.SpawnBall();
Destroy(gameObject);
}
}
This code also works perfectly fine, when Die() is called the sound plays, the gameobject is destroyed and a new ball spawns just like it does at the start of the scene.
The Die() is called in another script on another gameObject:
public class DeathFieldScript : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
BallScript ballScript = other.GetComponent<BallScript>();
ballScript.Die();
}
}
This all seems fine to me and it functions, but the problem is.
The following code (Class BrickScript is attached to the brick objects in the scene) executes just fine the first time, but after the ball object dies and a new one gets instantiated just like the previous one, the code returns with a NullReferenceException, even though the ball is right there in my screen and still dies like intended.
public class BrickScript : MonoBehaviour
{
public enum BrickType {Damagable, Normal, Coal, Iron, Gold, Lapis, Diamond, Chest}
public BrickType brickType;
public Material materialBroken;
public AudioClip[] deathSound;
public int pointValue = 1;
public int hitPoints = 1;
private int takeDamage;
void OnCollisionEnter(Collision col)
{
BallScript currentBall = GameObject.FindWithTag("Ball").GetComponent<BallScript>();
if (currentBall.IsUpgrade()){
takeDamage = 2;}
else{
takeDamage = 1;}
hitPoints = hitPoints - takeDamage;
if (brickType == BrickType.Damagable && hitPoints == 1){
AudioSource.PlayClipAtPoint(deathSound[Random.Range(0,deathSound.Length)], transform.position,0.3f);
this.GetComponent<Renderer>().material = materialBroken;
}
if(hitPoints <= 0)
{
Die ();
}
}
void Die()
{
AudioSource.PlayClipAtPoint(deathSound[Random.Range(0,deathSound.Length)], transform.position,0.3f);
Destroy(gameObject);
}
}
public class InputManager : MonoBehaviour {
void Update ()
{
if (Input.GetKeyDown(KeyCode.Z))
{
BallScript cheatScript = GameObject.Find("Ball").GetComponent<BallScript>();
cheatScript.Die();
}
}
}
Why can the two scripts above find the ball gameobject fine the first time it’s instantiated, but can’t find it after it dies and another ball is instantiated?
It worked fine before.