One of the weapons of Steredenn is a big blue laser. This deadly weaponry will slow your ship down but will also allow you to release a gigantic ray of energy onto your enemies to smash them all. Yep, it’s that cool.

Yet, the laser needed a different approach on how to implement it in the game. That’s what we are about to explain today.

While Plus is revealing some 2D art techniques, Damien is mostly going to talk about code.

So, it’s time for some gamedevfu!

Damien: for this first time I will explain how most lasers work in Steredenn.

The idea is to write a mini Unity tutorial that could be re-used in another game.

FYI, Unity is the name of the game engine that we use for Steredenn. If you are new to Unity, we definitely recommend this tutorial. ;)

I won’t go into details: you will have to add your own collision/damage/weapon logic, but you will get the basics on how to create a laser.

Sprites

First thing first, we need 3 sprites (Stallone, Schwarzenegger, Statham) to make an expandable laser:

a start sprite that should be placed at the end of the weapon.

sprite that should be placed at the end of the weapon. a middle sprite that you can extend without deform.

sprite that you can extend without deform. an end sprite to show the laser’s impact on its target.

Note: the middle sprite should have a width of 1 unit (The default in Unity is 100px . Have a look at the PixelsToUnit import setting). This way we can adapt its width to a perfect size.

The easiest way to handle these sprites for the laser in Unity is to create 3 prefabs, one for each sprite.

Those prefabs should only have a SpriteRenderer component for now.

The script setup

Next step, create a script. Let’s name it LaserScript (since we like to be very subtle and original).

Create an empty game object (“Laser”?) and attach the script to it. Nothing too fancy for now.

Open the script in your favorite code editor (I’m sure it’s not MonoDevelop).

Add 3 public fields to handle the 3 prefabs we created in the previous step:

[Header("Laser pieces")] public GameObject laserStart; public GameObject laserMiddle; public GameObject laserEnd;

Then, fill the fields in your GameObject of your Scene. And we’re okay for what comes next.

Creating the laser start and middle

Go back to your code editor: it’s time to write things. To simplify we will make the laser shoot continuously, but the ray will be affected by any Collider2D going through it.

Let’s create the laser base.

In Update, instantiate the prefab and attach it to the Laser. We also need to store the created object.

private GameObject start; void Update() { // Create the laser start from the prefab if (start == null) { start = Instantiate(laserStart) as GameObject; start.transform.parent = this.transform; } }

We will do the same thing for the middle part, BUT not for the end. The end is created only if we hit something.

private GameObject start; private GameObject middle; void Update() { // Create the laser start from the prefab if (start == null) { start = Instantiate(laserStart) as GameObject; start.transform.parent = this.transform; start.transform.localPosition = Vector2.zero; } // Laser middle if (middle == null) { middle = Instantiate(laserMiddle) as GameObject; middle.transform.parent = this.transform; middle.transform.localPosition = Vector2.zero; } }

Launch and… you should be quite disappointed:

Both lasers are placed at (0,0) , stacking each other. Don’t worry, it will be solved in the next part!

The laser length

This is the interesting part: how do we know the laser length? - If we don’t touch anything, it’s “infinite”. - Otherwise, it’s the length between the object and the laser source, minus the start and the end sprites.

Raycaysting will be our friend. It sounds scary but it’s dead simple: the physics engine throw an invisible ray in the direction you ask and tells you if the laser hit something.

The same phrase but in code:

// Define an "infinite" size, not too big but enough to go off screen float maxLaserSize = 20f; Vector2 laserDirection = this.transform.right; RaycastHit2D hit = Physics2D.Raycast( this.transform.position, laserDirection, maxLaserSize );

So if hit.collider is not null, we have touched something! Otherwise, it’s simply infinite.

The distance from the non-null hit and the laser is easy to compute:

float currentLaserSize = Vector2.Distance( hit.collider.transform.position, this.transform.position );

Now, we simply have to place the sprites.

Note: we consider that the pivot is at the center of the sprite (default). It’s slightly easier if you place it at the laser’s source.

Here is the full documented code with all the features:

https://gist.github.com/Valryon/566c02f3c5808dcd9968

Testing

How to test a collision with an object?

Well, simply add a new sprite with a Collider2D attached to it, or maybe a simple cube (but with a Collider2D).

A demo with a cube:

And… done! Wonderful, isn’t it?

I hope you enjoyed this little tutorial. :)

Damien out.

Feel free to send us any feedback and stay tuned for more!

— Steredenn’s team.