Many ‘sandbox’ type games are built around the idea of letting players place and build things in the world. Your players might be placing turrets to defend from crazy hordes of orcs, building houses and structures for their virtual families, or just putting up barriers to keep other players and zombies away. Whatever the game, it’s usually done by putting the object on the mouse cursor and letting the player move it around until it’s in place, then place it by clicking the mouse. Today, I’ll show you how to get started with your own placement system in Unity3D. We’ll build a Unity3D Building Placement system that allows you to place and rotate objects with the mouse cursor.
Environment & Art
To start, you’ll need some sort of environment to place objects on. You can grab just about anything from the free environments section of the asset store. I’ll be using this Free Autumn Mountain.
The mountain does not have a mesh collider though, so I need to add one first
In the mountain scene, the camera that’s placed is a bit high, and not tagged as “mainCamera“. I moved it a bit and set the “mainCamera” tag on it.
We’ll also need something to place. We could use a cube or some other primitive, but that’s a little boring, so I’m downloading a free turret from the asset store.
The Code – Ground Placement Controller
To make our placement work, we’ll need a new c# script. I’m going to name it GroundPlacementController.cs
Let’s take a look at this code and see what’s going on..
We start off with two serialized fields. One for the prefab we’d like to place and another for the hotkey we’ll use to create a new object. We keep these in private serialized fields so we can modify them in the editor later.
There are also two private fields, one to hold the object we’re currently placing, and another to deal with rotation.
In our Update method, we call a few things. I prefer to call a couple well named methods in Update whenever possible, instead of doing actual work. This makes it easier to see what’s going on at a quick glance and makes the code much easier to read.
Our first method checks to see if the player has pressed our new object hotkey (defaulted to A). If they do, we either create a new object to place by using Instantiate, or we destroy the current one that’s on the cursor. This lets our player cancel the placement easily if they change their minds.
Next, we check to see if there’s an object being placed – aka assigned to currentPlacableObject.
If there is, we jump into our movement method.
In here, we do a raycast from the mouse position into the world. The Camera’s ScreenPointToRay method will generate a ray beaming straight into the scene from our viewport. This means we’ll get a physics ray that goes exactly where we click.
If we click on something that has a collider, the raycast will return that object in the hitInfo object we declare on line 46, and it will return true, running the code to place our current object at that hitinfo.point.
We’ll also set the rotation of the object using FromToRotation. This will make the object always point upward, so if we place it on a slope, it’ll look right and not just clip through sideways.
Next, we go into the method to rotate based on our mouse wheel. This assumes we want the player to be able to adjust the orientation of their placed objects..
In here, we adjust the mouseWheelRotation by the mouseScrollDelta Y value. Then we rotate the current object using the Up vector and the current value of the mouseWheelRotation. We also multiply it by 10 to make it a bit faster / more sensitive.
The final method is there to ‘place’ or release our object. All we do here is check for a click, and if we get one, we clear out the currentPlaceableObject.
Adding the Manager
Create an empty gameobject in the scene.
Add the GroundPlacementController component.
Assign the turret prefab (or your own)
Conclusion / Extensions
This covers the basics of placing an object with your mouse cursor. In a bigger game, you may want to extend out the object selection, maybe have an array of placable objects and a hotkey to cycle through them, or even a full UI to select one. You could also fire some event when the object is released, play an animation.. set it to start firing? You could also swap the material when the object is being placed and give it a holographic look.