SkillSwap: Making A 2 Player 2D Game With Unity

SkillSwap Icon[UPDATE] We have a brand new Unity tutorial which uses the new built-in 2D sprite and physics systems that Unity added in version 4.3. You can find it here.

I recently presented a step-by-step workshop titled “Making A 2D Sprite-Based Game With Unity” to the Toronto SkillSwap community which is “A collaborative group for folks interested in sharing their skills and training with other developers in Toronto, and for folks interested in learning!”.

Around 50 people showed up to the 3 hour workshop and although we tried our hardest to get through all of the content, we only completed about 1/2 of the project before it was time to move on to the beer drinking portion of the event.

So while I still had all of the project steps fresh in my mind, I figured it would be a good idea to go through the workshop at home and screencast the whole thing so that everyone could get a chance to follow along with the complete tutorial.

Here’s a look at what the completed project looks like, because you know; editor screenshots in blog posts look cool.
SkillSwap 2d game editor

Before you jump into the video, here’s all the stuff you’ll need to complete the project:

And here’s the screencast:

Calculating Orthographic Camera Size

If you’re wondering how I came up with the 6.25 orthographic size used in this project, here’s a handy formula for figuring out the orthographic camera size which was provided by Jason Caldwell.

x = screen width in pixels
y = screen height in pixels
s = sprite height or width (whichever is larger) in pixels
 
x / ((( x / y ) * 2 ) * s )

More Unity 2D Game Tutorials

Make A 2D Game in Unity3D Using Only Free Tools Part 1
Make A 2D Game in Unity3D Using Only Free Tools Part 2
Make A 2D Game With Unity3D Using Only Free Tools Part 3
Make A 2D Game With Unity3D Using Only Free Tools Part 4
Make A 2D Game With Unity3D Using Only Free Tools: Beginning Enemy AI With A* Pathfinding

Show Your Support

If you find our tutorials useful, please considering buying one or more of our games and apps for iPhone and iPad. Your support helps to keep the tutorials flowing!

Giant Moto: High flying arcade style motocross action!
Small Space: Fly a spaceship, eat space creatures, get huge, score point!
Holeshot Drag Racing: High speed drag racing action!
Alien Booth: Transform pictures of your friends into awesome aliens!
iSpoof Walken: A hilarious look into the world of Christopher Walken!
Gaga Eyes: Transform pictures of your friends to give them huge anime eyes!

About the author

Tim MillerTim Miller is a veteran game developer with over 15 years experience in the video game industry working as a Level Designer and Lead Level Designer at LucasArts, Secret Level and Nihilistic Software. He co-founded Rocket 5 Studios with his wife Cathy and their dog Rocket in 2009. Twitter, LinkedIn, Portfolio

Share/Bookmark
  • Pingback: Video game design skill swap at hit at GBC : The Dialog

  • http://profiles.google.com/maddox.br Breno Azevedo

    Very good tutorial, congratulations. Just shared it with my level design students :)

  • Pingback: Aymeric Lamboley » First month as a freelancer completed!

  • David Valachovic

    At the end of the tutorial, everything is fine except player 1 can’t go inside his goal, the score goes up when he touches it, but can’t go inside unless I untick ‘collidable’ but then it doesn’t count his score of course. Any ideas?

    Thanks for the great tutorial too!

  • Vitor Almeida da Silva

    Amazing stuff.

  • http://www.rocket5studios.com/ Tim Miller

    Check to make sure that you don’t have the trigger part of the goal assigned to the Ground layer since the player is set to collide with anything in that layer.

  • ShadowCloud

    I am having trouble with the ball, when the game is started it falls through the ground. I’ve checked the settings with the video but it hasn’t worked =/

  • David Valachovic

    Does the Ball GameObject match these settings and have the Ball (Script) on it?

    http://imgur.com/4ELn5WD

  • http://www.rocket5studios.com/ Tim Miller

    Make sure the ball settings are correct and that the ground is in the “ground” layer and that the Z translation on the ball and ground are both 0 so that the ball isn’t falling behind or in front of the ground.

  • vicman4

    Amazing tutorial. Just a noob question. Why do you develop your own Character class instead of use a Unity’s CharacterController?

  • ShadowCloud

    The ball settings are all correct except the sphere collider material, which it currently has none. The z translation is 0 for the ball, and all the brick tiles have the ground tag, but the brick z translation is locked at Z-0.00672 which do not seem right.

    I have also had this show up in the console

    UnityException: Tag: Ball is not defined!

    Player1.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Scripts/Player1.cs:82)

    Not sure if its related.

  • Adam Keating

    Great tutorial, but I’m running into an issue with the sprites that i’m using. Did my own custom characters and animations, and for some reason the tiling is off. Easy to fix, but as soon as you hit play, it resets, like it was originally in play mode. What am I missing?

  • Chas Sakayigun

    Hello there great job on the tutorial. I was wonder if you could take the world wrap off so you can expand your level. thanks again by awesome jod dude

  • Chas Sakayigun

    sorry but where do you change Screen wrap

  • http://twitter.com/gullwings13 Trev Smith-Holbourn

    I had a similar issue myself. I had “Is Trigger” set to true for the bricks/ground. Changing it to false seems to have fixed it.

    Cheers

  • http://www.rocket5studios.com/ Tim Miller

    Look in Character.cs lines 160 to 170 control the screen wrap.

  • http://twitter.com/getbiks Bikash Agarwal

    hi.. A very nice tutorial.. before this i was using a general approach to make a 2d game.. like make a cube and assign a texture to it.. and i made a simple 2d animation script which was handling the animation but it was very limited as no way to control it from one script and very troublesome. Using Orthello is so much advance and helpful.. Thanks a lot.. I need one more information though.. Can u explain how u made the font sprite sheet?? if i wanna use my own personal font ho to do tht?? i used to use 3dText game object before but this sprite way is way more better.. Any kind of help will be appreciated.. thanksa lot..

  • Gearface

    Thanks for the great tutorial! I was just wondering why you put a rigid body on the character if the physics is all controlled in the script?

  • http://www.facebook.com/chris.helmin.5 Chris Helmin

    Need some help :/ On the player container, I turned off use gravity, turned on kinematic like you said but then the player no longer falls… What’s up?

  • http://twitter.com/itreallyisamre Ian Burnette

    Great tutorial. Thanks for your clear and concise teaching!

  • http://www.rocket5studios.com/ Tim Miller

    He doesn’t use the box collier for collision, he uses raycasts. So when he’s in the air, adjust the position and distance of the raycasts to get the affect you want.

  • http://www.rocket5studios.com/ Tim Miller

    A rigidbody is always required in order to get OnTrigger events.

  • http://www.rocket5studios.com/ Tim Miller

    Instructions on how to create text with Orthello is here: http://www.wyrmtale.com/orthello/sprites#textsprite

  • http://www.facebook.com/chris.helmin.5 Chris Helmin

    Thanks for that, dunno why I kept overlooking that, and indeed fixed my problem quite easily!

  • Matthew

    Great tutorial. I’m trying to adapt some parts of this into a game for a class I am taking. Do you have any input on how one might change the functions to pick up and throw the ball if:
    1. There are multiple balls in play
    2. Some balls may be generated during game play (rather than just one ball at the start)

  • Matthew

    So funny. I ask this question and then I find exactly what I need through some more trial and error on my part. I swear, I felt as though I exhausted all options before even posting here.

    Once again, great tutorial.

  • http://twitter.com/tmountain Travis Whitton

    First off. THANKS for the awesome tutorial! I worked through from start to finish, and I’m also having a similar issue. Team1Goal is acting as collidable for both players. This prevents player 1 from ever scoring. If I change the layer to Team2Goal for both goals, it works great. I’ve looked through the scripts, and it doesn’t look like there’s anything related to collision for either goal, so I’m pretty confused.

  • http://twitter.com/tmountain Travis Whitton

    I just “solved” this by adding an additional constant in xa.cs for Team3Goal=11 and then changing the references to Team1Goal in Ball.cs to point to Team3Goal. From there, I changed the layer for the team 1 goal sprite to also point at Team3Goal (mapped to slot 11), and it worked. I have no idea why the Team1Goal layer is colliding, and this is obviously a big hack, but it works!

  • http://www.rocket5studios.com/ Tim Miller

    Glad to hear you figured it out! Sorry I couldn’t help, but that was a pretty big change to solve.

  • Karlos Carrijo

    There’s actually a small “bug” on the Character.cs that comes with the project files (not the finished project files). On line 60 we have:

    protected int groundMask = 1 << 9 | 1 << 8; // Ground, Block
    just replace that to:
    protected int groundMask = 1 << 8; // Ground

    Also, line 61 can also be removed (commented out), since the variable "blockMask" is not used anywhere.

  • Doctor Terminus

    This helps a lot getting started with Orthello. What is the best way to add a background image the same sizes as the viewing area using Orthello? Great tutorial, thanks!

  • James Shasha

    Thanks for the tutorial! I have a weird problem where player 1 will fall through the world after I hit ‘play’. he still can jump and collect the ball. Bizzarely, if I jump him through the edge of the screen, he wraps around and suddenly collides just fine. I’ve been through the scripts and I can’t seem to find any reason for it; I even copied and pasted the contents of player2 (making slight adjustments) into player1, as player2 seems to work fine. Any idea what this might be?

  • Joshua Whiting

    I don’t understand the equation you used to get the camera size. Which sprite (s) is it referring to? The largest one in the scene? The most important or most commonly used one? 6.5 seems to be approximately the number you’d get if you were referring to the player size… is that what you’re referring to? I just want to know how to adapt the formula to a different game. Thanks!

  • Pingback: Mana Sphere, el juego de Septiembre de #1GAM | Planet Bit Games

  • Pingback: Mana Sphere our #1GAM of September | Planet Bit Games

  • alpants

    came here looking for this. Thanks!

  • http://kickfolio.com/ Chris Nolet

    The formula can be simplified to: Camera Size = Screen Height / Sprite Height / 2 — or y / s / 2. It basically says, that if a sprite is ’1 unit` tall and 32 pixels high, then the screen needs to be `12.5 units` tall (equivalent to 400 pixels high). The camera size is always half of what fits on the screen, so then we just halve it.

  • Joshua Whiting

    Sorry, but I still don’t know what sprite you’re referring to. When you say “Screen Height / Sprite Height / 2″ which sprite’s height are you referring to? The player? The background? The goal? Or whatever sprite is exactly one unit tall?