Block building

Have you ever wanted to let the player build blocks, like in a game like Minecraft?

Well now you can! BlockPlacer has been created to let you place blocks to your heart’s content.

Detailed comments have been included in the script so that you can look into how it works. The full explanation is too lengthy for a tutorial.

Make sure you place the FPSController object on the Player layer to avoid raycasting into yourself.

using UnityEngine;
using UnityEngine;
using System.Collections;

public class BlockPlacer : MonoBehaviour {

	//Handles # of blocks the user has
	public bool unlimitedBlocks = false;
	public int blocksLeft = 0;

	//If the player wants to lock the cursor somewhere else instead, they can do that.
	public bool lockCursor = true;

	//static reference to the script. This is so blocks can be added via a static method.
	static BlockPlacer obj;

	//The block prefab to instantiate
	public GameObject blockPrefab;

	//Maximum range that the player can place a block from
	public float range = 7f;

	int layerMask = 1 << 8; 	void Start () { 		//This assigns the static reference 		BlockPlacer.obj = this; 		layerMask = ~layerMask; 	} 	void Update () { 		//Locks the cursor. Running this in update is only done because of weird unity editor shenanigans with cursor locking 		if (lockCursor) { 			/// ERRORS? Are you getting errors on the following line of code? 			/// If so, you're probably using Unity 4 or earlier. 			/// To fix this, add // to the start of the following line 			Cursor.lockState = CursorLockMode.Locked; 		} 		/// And remove // from the start of the next line of code 		//Cursor.lockCursor = true; 		//Make sure the player has enough blocks 		if (blocksLeft > 0 || unlimitedBlocks) {
			//Place blocks using the LMB
			if (Input.GetMouseButtonDown(0)) {
				//Make a ray and raycasthit for a raycast
				Ray ray = new Ray(transform.position, transform.TransformDirection(Vector3.forward));
				RaycastHit hit;

				//Perform the raycast
				if (Physics.Raycast(ray, out hit, range, layerMask)) {
					//The raycast is backed up so that placing works and won't place blocks inside of the ground.
					//After testing, 0.2 units back had the best result
					Vector3 backup = ray.GetPoint(hit.distance - 0.2f);

					//Round the placement so they place like blocks should
					Vector3 placeAt = new Vector3(
						Mathf.RoundToInt(backup.x), Mathf.RoundToInt(backup.y), Mathf.RoundToInt(backup.z));

					//Instantiate the block and save it so that we can do other stuff with it later
					GameObject block = (GameObject)GameObject.Instantiate(blockPrefab, placeAt, Quaternion.Euler(Vector3.zero));

					//Remove a block from the player's "inventory"
					if (!unlimitedBlocks) {
						blocksLeft--;
					}

					//If the block collides with the player, remove it. We don't want the player to get stuck in their own blocks.
					if (block.GetComponent<Collider>().bounds.Intersects(this.transform.parent.GetComponent<Collider>().bounds)) {
						//If they are, destroy the block
						GameObject.Destroy(block);
						//Make sure that the player gets their misplaced block back.
						if (!unlimitedBlocks) {
							blocksLeft++;
						}
					}
				}
			}
		}
	}

	void OnGUI() {
		//This is the crosshair
		GUI.Box(new Rect(Screen.width / 2 - 5, Screen.height / 2 - 5, 5, 5), "");
	}

	//Static adding of blocks. This isn't needed but definately helps a lot
	public static void addBlocks(int i = 1) {
		BlockPlacer.obj.blocksLeft += i;
	}
}

Adding it to your project

  1. Copy the entire script from the pastebin.
  2. Then go to Unity, click Create in the Project panel, and click C# Script.
  3. Name it BlockPlacer.
  4. Double-click it to open up the script, and replace everything with the code you copied.
  5. Save it, and go back to Unity.

Attach the script

  1. Go to your player in the Hierarchy, and click the down arrow next to them to expand its contents.
  2. Then click FirstPersonCharacter.
  3. Drag the BlockPlacer script into the inspector.
  4. Create a new cube. Drag the cube into the project panel.
  5. Then delete the cube from the scene.
  6. Go back to where you put the BlockPlacer script, and drag the cube from the project panel into the box that has the label “Block Prefab”.

You’re done!

Test it

You should be able to walk around clicking to place blocks.

block placer

Troubleshooting

If you get errors:

  • Check that you’ve assigned the block prefab variable.
  • Make sure BlockPlacer.cs is the file name of the script and at the top of the script.
  • You must set the number of blocks to place or make block placing unlimited.

Writing code for BlockPlacer

In order to place blocks, you need to write some code to get blocks. Alternatively, you could just click the Unlimited Blocks checkbox, but where’s the fun in that? Make a block that you can pick up, much like you made coins in that tutorial. Instead of adding a coin when you pick it up, make write:

BlockPlacer.addBlocks();

That will give you a block that you can now place.

Now that you can collect blocks, you can make all sorts of puzzles and challenges that require placing blocks to get around!

Author

Tutorial by Trevor Paley, a volunteer mentor at Hack The Future

Leave a comment