Way back in the first part of this series, I mentioned that you can make complex collision objects in 3D packages like Maya or Blender to match the shape of your 2D sprites. Unity3D provides basic primitives like cubes and spheres, but sometimes you need more complex shapes to match the contours of the objects in your scene.
Even though this post is part of the “Creating 2D Games” series, these techniques will work for 3D games too. In fact, I created all of the 3D models for my iOS game Giant Moto using many of these techniques. I’ll be using Maya 2008 in this tutorial, but these concepts can be applied to your favorite 3D modeling package.
Recommended Reading
- Creating 2D Games with Unity3D Part 1
- Creating 2D Games with Unity3D Part 2
- Creating 2D Games with Unity3D Part 3
- Creating 2D Games with Unity3D Part 4
Rocket’s Game, Example 1
This example shows how to make collision objects to match the shape of your 2D game characters. When a bullet collides with the Cat’s space ship, a small sphere will appear briefly to show where the bullet hit the ship’s collision mesh.
Click the image to load the example game in a new window:
Making Collision For Rocket’s Ship
You can download “RocketsGame” project folder here. Remember that in order for the sprites in my project to display properly, you’ll need to use the Sprite Manager 2 plugin which is not included in my project. Once you have the project open in Unity, double click your “SM2 1.84.unitypackage” to import the package into the project. After that, you might also need to reassign the Sprite Material to the sprites in the scene – refer to Creating 2D Games with Unity3D Part 2 for details on how to do that. Note that I’m using Sprite Manager 2 v1.84.
After your project is set up and your sprites all look correct, we need to take a screenshot of the scene so that we can create a 3D model in Maya that will match the sprites exact shape. Use the following script to take a screenshot of your game (this is also included in controls.js in the project files).
1
2
3
4
5
6
|
function
Update () {
if
(Input.GetKeyDown(
"s"
)) {
print(
"screenshot"
);
Application.CaptureScreenshot(
"Screenshot.png"
);
}
}
|
- To take a screenshot, press the play button in Unity and then press the “s” key on your keyboard (assuming you’re using the script above). The word “screenshot” should print to the console to confirm it worked and you should find Screenshot.png in your project directory. Here’s what mine looked like.
- Open up Maya and confirm the following settings. Go to Window –> Settings and Preferences –> Preferences and then click on Settings. Make sure the “Up axis” is set to “Y” and Linear Working Units is set to “Centimeters”.
- To confirm that everything is working between Maya and Unity, create a 1x1x1 cube at 0,0,0 in Maya and then save the file in your project eg.RocketsGame/Assets/Models/cube.ma. Then switch back to Unity and drag the “cube” object into your scene. While still in Unity, go to Game Object –> Create Other –> Cube to create a cube. The cube you created in Maya and the one you created in Unity should be exactly the same size.
- Next we need to find the Unity/Maya unit size of the Screenshot.png file you made in step 1. Scale up the Unity cube you made in step 2 so that it fills the Game view exactly. My example project is set to 480×320 so my cube fills the screen at Scale X:15, Scale Y:10. Since we confirmed in step 2 that our Maya to Unity scale is 1:1, now we know how big to make the image plane in the next step.
- In Maya, create a plane Create –> Polygon Primitives –> Plane and then drag a plane out on the grid. Set the Translate X, Y and Z to 0 and set Rotate X to 90. Under polyPlane1′s INPUTS, set Width to 15 and Height to 10 (assuming your project is 480×320 like mine).
- With the plane selected in Maya, right click + hold on the plane and then go to Assign New Material –> Lambert. In the Attributes editor, click on the the little black/white checkerboard icon next to Color to bring up the Create Render Node window and then click on File. Now click on the the little folder icon next to the Image Name filed and browse to the location of the Screenshot.png we created in step 1 and click ok. You should see the .png on your plane, if you don’t press 6 on the keyboard to switch to texture view.
- Go to Create UV’s –> Planar Mapping and adjust the Projection Attributes in the Attributes Editor until the image looks correct on the plane. Click here to see what mine looks like.
- Now we’re finally ready to create the collision to match the sprite. Switch to the Front camera so that you’re looking at an orthographic view of the image. Go to Mesh –> Create Polygon Tool and trace out the shape of the sprite. Once you have the shape you like, you need to extrude the object to give it depth so that objects in your scene will be able to collide with it in 3D space. Go to Edit Mesh –> Extrude and extrude the mesh on the Z axis only so that it has about 1 unit of depth.
- You also need to make sure that the normals on the collision are facing out. With the object selected, open the Attribute Editor and then under Render Stats, make sure that “Double Sided” is unchecked. Now you should be able to see the actual polygon faces on your object. If any faces are pointing inward, you need to select those faces and then go toNormals –> Reverse.
- Center the pivot on your mesh and then snap the object to 0,0,0 on the grid to make sure that it’s perfectly centered in the scene and then Freeze Transforms to zero out the transforms.
- Now you could just save the scene into your project folder to import it into Unity. But the scene also has a plane with Screenshot.png on it which we don’t want in our scene – our sprites are being drawn with Sprite Manager so we don’t want this textured model in there too. Select the object in Maya and then go to File –> Export Selection, then click Export Selection and browse to the location in your Unity project where you want to save the model.
- Switch back to Unity and drag the collision object (“rocket” in my case) from the Project view into the Scene view. Set the Transform X, Y and Z to zero and you might also need to rotate the object 180 on the Y – I think the camera in Maya is on the opposite side as the camera in Unity so you can end up with mirrored results if everything isn’t setup properly.
- One more thing, we need to generate colliders on the mesh. With the object selected in the Project view in Unity, you should see the FBXImporter settings in the Inspector. Click the Generate Colliders checkbox and then click Apply.
Here’s what my finished collision looks like in Unity (I put a transparent material on the model so you can see the sprite through it).
Whew. That looks like a lot of work, but once you do it a few times it’s a pretty quick process. As always, if anyone knows of a quicker way to do this please let us know in the comments.
What you have now is a collision object that’s very much like a stock Unity cube or sphere Game Object which means you can treat it like any other object in your scene. I’m not going to go into detail on how to make this new collision object into a playable character, but basically you just need to add your player sprite object as a child of the collision so that the sprite will move with the collision, uncheck the Mesh Renderer on the collision so it’s not visible and then add your control script to it. Again you can download the project here to see exactly how I have my scene setup.
Pachinko Thing, Example 2
Here’s another example that applies the techniques from above to static and animated level geometry. You can download the “2DPachinko” example here (again, you need to provide your own Sprite Manager plugin).
Click the image to load the example game in a new window:
And here’s what the collision looks like in Maya and in Unity.
Conclusion
This post demonstrated a couple of the possibilities when combining 2D art with 3D collision objects in Unity3D. I’m always looking for ways to improve my own workflow, so if you see any errors or have any suggestions, please feel free to post in the comments. Oh and the little kitty cat that’s flying the red rocket is from the Open Clip Art Library.
This post is part of iDevBlogADay, a group of indie iPhone development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, or Twitter.
//