Need to combine 2 scripts into 1 and lose a Static variable ? (Solved)

OK… I had two scripts running nicely, one instantiated an object and threw it into the air every x seconds, the other destroyed the object ready to instantiate a new one.

instantiate script-

using UnityEngine;
using System.Collections;

public class LavaThrower : MonoBehaviour
{
	
	public Transform lavaPoint;
	public Rigidbody lavaBallPrefab;
	public static int ballNumbers = 0;
	public int throwPower;
	
	
	void Update()
	{
		if(ballNumbers <=0)
		{
			ThrowTheLavaBall();
		}
	}
	
	void ThrowTheLavaBall()
	{
		ballNumbers += 1;
		Rigidbody lavaBall;
		lavaBall = Instantiate(lavaBallPrefab, lavaPoint.position, lavaPoint.rotation) as Rigidbody;
		lavaBall.AddForce(lavaPoint.up * throwPower);
	}
}

destroy script -

using UnityEngine;
using System.Collections;

public class DestroyLavaBall : MonoBehaviour
{
	
	void Awake()
	{
		StartCoroutine(DestroyTheLavaBall());
	}


	IEnumerator DestroyTheLavaBall()
	{
		yield return new WaitForSeconds(6.5f);
		LavaThrower.ballNumbers -= 1;
		Destroy(gameObject); // Destroy Self
	}

}

All was going well until I placed another spawner into my scene and then realised that because I’d used a static variable one script was overwriting the other.

I think (please correct me if wrong) that I’d be better off with one script per spawner that was handling the instantiate AND the destroy. Therefor removing the need for any static variables.

And that’s where my problem is. I’ve tried a few approaches (and to be honest) I’m screwing it up more than I’m making progress. So I’m looking for some suggestions as to how I write/structure the script.

As usual any help is greatly appreciated.

And now you know why static is evil. :slight_smile:

Keep two scripts. But give the lavaball a reference back to its spawner. Something like this.

Remove the static

Add at line 26 of the first script

lavaBall.GetComponent<DestroyLavaBall>().lavaThrower = this;

At the top of the second script

public LavaThrower lavaThrower;

Chane line 16 of the second script to

lavaThrower.ballNumbers--;

Note that this is not the best way to do it. You’ll discover the principle of encapsulation later, and realise that this could still be made better. You are welcome to google the term to avoid heart ache. Or steam ahead and post back here when you come across the problem yourself. (Insert evil grin here)

You’re right that you need to stop using static for ball numbers if you want multiple spawners but whether you want to use one or two scripts is basically a design choice.

If you want to combine the scripts then you could add the following to LavaThrower

public void DestroyTheLavaBall(){
    StartCoroutine(DestroyTheLavaBallRoutine());
}
IEnumerator DestroyTheLavaBallRoutine()
{
    yield return new WaitForSeconds(6.5f);
    ballNumbers -= 1;
    Destroy(gameObject); // Destroy Self
}

Then since the new DestroyTheLavaBall() method is public you can run it instead of creating new DestroyLavaBall objects. For instance

public class Controller{
    public GameObject lavaThrowerObj;    
    void Start(){
        lavaThrowerObj.GetComponent<LavaThrower>().DestroyLavaBall();
    }
}

You could also have two separate scripts. For instance you can use the following.

public class DestroyLavaBall : MonoBehaviour {
    void Awake() {
        StartCoroutine(DestroyTheLavaBall());
    }
    IEnumerator DestroyTheLavaBall() {
        yield return new WaitForSeconds(6.5f);
        gameObject.GetComponent<LavaThrower>().ballNumbers-=1;
        Destroy(this); // Destroy Self
    }
}

Then you would use it something like

public class Controller {
    public GameObject lavaThrowerObj;    
    void Start() {
        lavaThrowerObj.AddComponent<DestroyLavaBall>();
    }
}

OK sorted. Now each spawner works independently of any others and I can set the spawn/launch times for each spawner.

here’s the script in case anybody else ever needs to do something similar -

using UnityEngine;
using System.Collections;

public class LavaThrower : MonoBehaviour
{
	
	public Transform lavaPoint;
	public Rigidbody lavaBallPrefab;
	private int ballNumbers = 0;
	public float waitTime = 6.5f;
	public int throwPower;
	
	
	void Update()
	{
       	if(ballNumbers <=0)
		{
			ThrowTheLavaBall();
		}
	}
     

	void ThrowTheLavaBall()
	{
		ballNumbers += 1;
		Rigidbody lavaBall;
		lavaBall = Instantiate(lavaBallPrefab, lavaPoint.position, lavaPoint.rotation) as Rigidbody;
		lavaBall.AddForce(lavaPoint.up * throwPower);
		StartCoroutine(DestroyTheLavaBallRoutine());
	}

	
	IEnumerator DestroyTheLavaBallRoutine()
 	{
		yield return new WaitForSeconds(waitTime);
		ballNumbers -= 1;
	}


}

Big thanks to @BoredMormon and @maccabbe Couldn’t have figured it out with the help and input from you guys. Appreciate the help from both of you.

:slight_smile: