How to do Lasers in Unity3D

I was recently asked about how the lasers were done in Star Wars Trench Run and I’d said I’d blog about that and a few other items, so here’s the first of a few.  This is the same material I covered at Unite 2009, so if you’ve seen the video or were there, there’s nothing new;)

Here we’ll cover one way of doing lasers with Unity3D that looks good and is performance friendly for the iPhone.  This isn’t meant to be exhaustive by the way, it’s just meant to be the base overview of what a laser *is* in Unity and how I managed it in terms of performance for the iPhone game.  So with that, let’s jump in to some steps on setting it up.

Create LineRenderer

0. First, Create an empty GameObject in your scene.

1.  Then, attach a line renderer component to your GameObject and position the GameObject where the tip of the laser cannon will fire from.  Why not just use a particle emitter?  This is because the ellipsoid particle emitter has a bug.  even if you set the size of the ellipsoid to 0 on all 3 axis or .0001, you will see that it starts at a random location on the z axis.  Unity acknowledged the bug.  So to fix this, since we can’t emit using the particle emitter from the cannon’s tip, we have to first show a line renderer.  Below are some typical settings you could use for a LineRenderer as a laser bolt:

Properties of a general LineRenderer for a laser

Here’s what it should look like in the Unity IDE when you get your GameObjects in place:

GameObjects with LineRenderes placed at the cannons

I created a class called LaserControl, and when I want it to show, this is literally what I do:

public var isShowingLaser:boolean = false;
function showLaser()
{
   if( isShowingLaser ) return;
   isShowingLaser = true;
   thisRenderer.enabled = true;

   yield WaitForSeconds (.05);
   resetLaser();
   isShowingLaser = false;
}

as you can see, it shows it for .05ms then hides it by calling reset laser which just does this:

function resetLaser()
{    
   this.renderer.enabled = false;
}

3.  So, then create your own class that extends MonoBehaviour and attach it to the GameObject that you added the LineRenderer to.

Create Particle Emitter

Now that we have this really nice LineRenderer laser that looks great coming from the tip of the cannon, we actually need to emit a laser to “fly” on it’s own path, right? So the concept for this is:  create empty GameObjects to server as 3D points for your emitter to “jump” to when you when it is to emit a laser from a particular cannon.  Since a particle emitter counts as 1 draw call for all of its particles, this makes it especially nice on an iPhone build.  Even better, it’s very lightweight on a web based game.

0.  Create 1 new GameObject for every cannon you have.  In this instance, I had 4 for the X-Wing, so I created 4 GameObjects with nothing in them.  Then give them names like TL, TR, BL, BR (topLeft, topRight, bottomLeft, bottomRight).

Here’s a screenshot of one of the emitter locations highlighted in the editor:

Empty GameObject serves as location for emitter later on

1.  Position these new GameObjects at the very end of the LineRenderer in your scene.  These will be the location that the emitter jumps to just before being told to Emit(1).

2.  Now, create a GameObject.  Then, with that GameOject selected, add: 1) Ellipsoid Particle Emitter, 2) Particle Animator, 3) Particle Renderer.

3.  In Particle Ellipsoid Emitter, set Local Velocity > z = -500.  This is the speed essentially.  If you want a faster laser, increase the number.  Make sure “Simulate in worldspace” is checked as this will allow emitted particles to carry on their path in world space once they’re fired.  Set the Ellipsoid to 0 on all 3 axis.  Finally, set Min Emitter Range = .0001 to make sure it fires from the closest location to the center of the GameObject as possible.  Like I said, with the bug, it’s a bit random on the z axis, but you’ll never see that in the game.  Leave the Particle Animator as is.

4.  Now the other bit of magic in making the laser is the Particle Renderer.  You’ll want to set “Stretch Patricles” = Stretched, with a length scale of 7 or so.  You can play with this number as it will determine how good your bolt looks in length.  Then set the “Max Particle Size” = .01.

Here’s a screen shot of the settings for the particle emitter and renderer ( the animator is left with its defaults ):

Particle Emitter settings

Conclusion

At this point, you have the physical objects in your scene to manage your lasers.  The last remaining step is to write a class that moves the emitter to each of those 4 emitter location GameObjects, tells the LineRenderer to show() and then emit 1 particle – BAM!  You now have lasers in Unity!

Hope this helps and hope you have a Bandit day ;)

About these ads
  1. Wow! This is great. Thanks for the explanation. I think I will spend some time in Unity this weekend trying to recreate and understand these concepts.

    • Khyrid
    • November 12th, 2010

    “So, then create your own class that extends MonoBehaviour ” <-Lost me there. Create my own what? extends huh? Where does somebody learn what that means?

    • :) That’s where you go and learn how to write code for Unity. If you use UnityScript (js files), just create a new JS file, and that will automatically extend MonoBehavior.

        • Khyrid
        • November 12th, 2010

        I always use Unity Script but I was getting some kind of error :( But yes I am just starting to learn to code. I have GML (game maker) coding experience, but it’s very different.

        All I want to do is have a gun that shoots using raycast (like the machine gun in the Unity FPS tutorial) and has a bullet trail. I don’t understand the Line Render’s involvement in this tutorial. And I don’t know how to tell the emitter to move anywhere or the other things in the conclusion.

        I guess visible projectiles that are not objects are just out of my league right now. :(

    • jlake
    • February 28th, 2011

    My LaserControler.js is like this:

    var delaySeconds : float = 0.05;

    function Start() {
    while(true) {
    yield WaitForSeconds (delaySeconds);
    this.renderer.enabled = !this.renderer.enabled;
    }
    }

  2. You’re using the “iPhone/Particles/Additive Culled” shader, but I can only find any shader named that as a download from vtc.com. I checked in Unity installs both with and without the Pro license. Where does it come from? If you have the rights, would you please publish the contents? I’m so far unable to achieve your results, which seems to be a result of not having that shader.

    • Just use Particles>Additive or even unlit>transparent. The unlit option would likely be faster than the additive.

    • Clayton
    • July 23rd, 2012

    Thanx a lot! I used this for a kind of sun light shine ray . Couldn’t have gone without it :)

    • f
    • December 6th, 2012

    Didn’t work for me, followed it step by step.

  3. In case someone is interested, here is an implementation of laser reflection. Text is in Brazilian portuguese but the code is pretty clean and simple; http://blog.octopusteam.com.br/2012/04/zim-lasers.html

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 794 other followers