[TIP] Communicating between scripts, and a little advice on statics

A couple of people have suggested an alternative method to the Shredder, and I’d like to go a little bit into some more detail for this. The reason this is suggested is simple; you won’t be restricted by screen size for your laser destruction shape. For more detail on this, check out Mustafa_Kahraman’s post here: Destroy Particles Without Shredder (there’s a few other threads too, this was just the first I saw).

There’s more you can do with a separate script than just destruction, though! Here’s my laser script, named FireBehavior (note that I’m using Unity 5, so my rigidbody script is a little different - I put my velocity into the laser script just as a matter of preference):

public float speed = 1f;
public float speedModifier = 1f;

Vector3 ceiling;

void Start () {
	// calculate speed for individual shot types
	GetComponent<Rigidbody2D>().velocity = new Vector3(0, speed * speedModifier, transform.position.z);

	float distance = transform.position.z - Camera.main.transform.position.z;
	ceiling = Camera.main.ViewportToWorldPoint(new Vector3(0,1,distance));
}

void Update() {
	if (transform.position.y > ceiling.y) {
		Destroy(gameObject);
	}
}

You’ll note a couple more public floats at the top of the screen - this is because I’ve made three different prefabs for lasers, called ‘Basic’, ‘SlowFat’ and ‘FastRed’. Each one has separate values in the game (Speed I’ve left as 1 across the board, but SpeedModifier is 7.5 for the ‘Basic’ beam, 5 for the ‘SlowFat’, and 10 for ‘FastRed’).

“Why are you doing this?” you ask? Inside my PlayerController.cs file, I’ve put in the following extra lines:

void Update () {
	if (Input.GetKeyDown(KeyCode.Space)) {
		InvokeRepeating("Fire", 0.00001f, fireRate);
	}

	if (Input.GetKeyUp(KeyCode.Space)) {
		CancelInvoke("Fire");
	}
}

void Fire() {
	var beam = Instantiate(projectile, new Vector3(transform.position.x, transform.position.y, transform.position.z + 1), Quaternion.identity) as GameObject;
	FireBehavior fireBehavior = beam.GetComponent<FireBehavior>();
	fireBehavior.speed = projectileSpeed;
}

Creating an object based on a script you’ve attached as a component to a GameObject allows you to communicate public variables between scripts without needing to define them as global static variables, which if you’re new to programming, you should try to avoid if you can - a global static can be very useful for some things, but down the line can make debugging a nightmare in projects that have tens of thousands of lines and tens if not hundreds of files. Get into the habit early of restricting the scope of your functions whenever possible - it’s good practice, and it’ll make your life a lot easier with answering weirder project issues down the line. This gets covered a bunch throughout this course, in more detail, but seriously seriously seriously I’ve spent months of my life in an adjacent programming field dealing with the ramifications of badly using global statics and I just… being more rigorous and strict with this knowledge earlier in my career would have saved me no end of grief.

So, what’s that code do? In my concept that I’ve pasted here, the idea would be that a ship might get long term upgrades to their weapons cooling (affecting the ‘projectileSpeed’ float inside the PlayerController) and that, during play, they may collect pickups to change the type of weapon they’re firing, each one having its own individual beam speed (which is where the ‘speed’ variable inside FireBehavior comes into play).

In play, this would be reflected as an entry level ship being able to fire (as an example, not exact numbers here) a Basic laser at a speed fast enough to clear the screen in one second, but a more advanced ship might be able to fire a Basic laser at a half-second screen clear speed.

Start considering how you can modularize your scripts as you develop - there’s some really cool things you could do down the line to make some really unique gameplay elements!

Privacy & Terms