ModularConstruction

From Unify Community Wiki
Revision as of 22:08, 12 March 2016 by Divinux (Talk | contribs)

Jump to: navigation, search

Author: Divinux

Contents

Description

This is a really basic version of a modular building system. Rust and Unturned use this kind of thing for houses and such, but it can also be used for weapons, corridors, spaceships, vehicles, anything that you can provide "building blocks" for.

ModularConstructionPreview.png

Usage

Set up the manager object

  • Create an empty GameObject and call it BuildingManager or similar. Attach this script to it.
  • Set the size of the Prefabslist to however many modules you have.

Set up a module

  • Create an empty GameObject. Give it a descriptive tag like "wall". Also name it "WallModule" or similar.
  • Add a model as a child to it.
  • Add a collider as a child as well.
  • Add a new sphere as a child. Tag it "handle". You can set this tag in the inspector of this script.
  • Make sure the sphere you just created has a collider, then tick the "Is Trigger" box.
  • Disable the sphere's mesh renderer.
  • Position this sphere where you want objects to connect. Your prefab may have multiple connections.
  • Make a prefab for this module.

Set up a preview

  • Just keep using the object you just created and make the following changes:
  • Add a transparent material to the mesh, to make it look like a ghost preview.
  • Disable the collider.
  • On all your handle children, disable the collider and enable the mesh renderer.
  • Name the object "WallPreview" or similar and make a prefab for it.

Add references to the manager

  • Now go back to the inspector of your BuildingManager and just drag your prefabs into the list "Prefabs".

You're done!

Code (ModularConstruction .cs)

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class ModularConstruction : MonoBehaviour 
{
	//distance at which objects can connect
	public float Range = 50f;
	//distance at which previews hover
	public float HoverDist = 10f;
	//tag for the position markers
	public string Tag = "handle";
	//currently selected part in the list
	//change this from wherever to have the player select an item
	public int Selected = -1;
	//list of all prefabs
	public List<Part> Prefabs = new List<Part>();
 
	//private stuffs
	RaycastHit hit;
	GameObject Preview;
	//list of all handles the prefab has
	List<GameObject> Handles = new List<GameObject>();
	//currently active handle
	int SelectedHandle = 0;
	//just a position holder
	Vector3 p;
 
	//a single object class, 
	//the actual part that gets instantiated,
	//and the preview model for it
	[System.Serializable]
	public class Part
	{
		public GameObject Prefab;
		public GameObject Preview;
	}
 
	void Update () 
	{
		//check for player selection
		//only needed for testing, feel free to delete
		CheckSelection();
		//if any item is "active"
		if(Selected != -1)
		{
			//check if anything was hit
			if(Physics.Raycast(Camera.main.ScreenPointToRay(new Vector3((Screen.width / 2), (Screen.height / 2), 0)), out hit, Range))
			{
				//enable preview
				EnableSelected();
				//check if hit object is a positioning handle
				if(hit.transform.tag == Tag)
				{
					//find correct position
					p = Handles[SelectedHandle].transform.position - Preview.transform.position;
					//move preview into position
					Preview.transform.position = hit.transform.position - p;
				}
			}
			//if not, just spawn it at default distance
			else
			{
				EnableSelected();
				Preview.transform.position = Camera.main.transform.position+(Camera.main.transform.forward*HoverDist);
			}
			// rotating
			AwaitRotation();
			// toggling the active handle
			AwaitHandleSwitch();
			//actually place the object
			AwaitPlacement();
		}
		else if(Preview != null)
		{
			Destroy(Preview);
			Handles.Clear();
		}
 
	}
	//enables the selected preview
	void EnableSelected()
	{
		if(Preview == null)
		{
			//instantiate if no preview is present
			Preview = Instantiate(Prefabs[Selected].Preview,Camera.main.transform.position+(Camera.main.transform.forward*HoverDist), new Quaternion(0,0,0,0)) as GameObject;
			FindHandles(Preview);
		}
		else if(Preview.transform.tag != Prefabs[Selected].Preview.transform.tag)
		{
			//if wrong preview is present, 
			//delete, then instantiate correct one
			Destroy(Preview);
			Preview = Instantiate(Prefabs[Selected].Preview,Camera.main.transform.position+(Camera.main.transform.forward*HoverDist), new Quaternion(0,0,0,0)) as GameObject;
			FindHandles(Preview);
		}
		else
		{
			//else just move the preview
			Preview.transform.position = Camera.main.transform.position+(Camera.main.transform.forward*HoverDist);
		}
	}
	//waits for the player to confirm placing the prefab 
	void AwaitPlacement()
	{
		if(Input.GetMouseButtonUp(0))
		{
			Instantiate(Prefabs[Selected].Prefab, Preview.transform.position, Preview.transform.rotation);
		}
	}
	//waits for player to rotate the object
	void AwaitRotation()
	{
		if(Input.GetKeyUp(KeyCode.Q))
		{
			Preview.transform.Rotate(90,0,0,Space.World);
		}
		if(Input.GetKeyUp(KeyCode.E))
		{
			Preview.transform.Rotate(0,90,0,Space.World);
		}
		if(Input.GetKeyUp(KeyCode.R))
		{
			Preview.transform.Rotate(0,0,90,Space.World);
		}
	}
	//waits for player to toggle the active handle
	void AwaitHandleSwitch()
	{
		if(Input.GetKeyUp(KeyCode.T))
		{
			if(Handles.Count > 0)
			{
				SelectedHandle++;
				if(SelectedHandle >= Handles.Count)
				{
					SelectedHandle = 0;
				}
			}
		}
	}
	//Finds all handles the prefab has 
	void FindHandles(GameObject g)
	{
		Handles.Clear();
		foreach(Transform c in Preview.transform)
		{
			if(c.tag == Tag)
			{
				Handles.Add(c.gameObject);
			}
		}
	}
	//PLACEHOLDER METHOD FOR SELECTING
	//REPLACE WITH WHATEVER
	//WAY YOU HAVE FOR THE PLAYER
	//TO SELECT ITEMS
	void CheckSelection()
	{
		if(Input.GetKeyDown ("1"))
		{
			if(Selected != 0)
			{Selected = 0;}
			else
			{Selected = -1;}
			SelectedHandle = 0;
		}
		else if(Input.GetKeyDown ("2"))
		{
			if(Selected != 1)
			{Selected = 1;}
			else
			{Selected = -1;}
			SelectedHandle = 0;
		}
	}
}

History

  • 12 March 2016 - Release
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox