ModularConstruction

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(Created page with "Category: MonoBehaviour Category: C Sharp Category: ReallySimpleScripts Hang on, still editing this... == CSharp - ModularConstruction.cs == <syntaxhighlight la...")
 
Line 1: Line 1:
 
[[Category: MonoBehaviour]]
 
[[Category: MonoBehaviour]]
 
[[Category: C Sharp]]
 
[[Category: C Sharp]]
[[Category: ReallySimpleScripts]]
+
Author: [[User:Divinux|Divinux]]
  
Hang on, still editing this...
+
== 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.  
  
 +
== 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.
  
== CSharp - ModularConstruction.cs ==
+
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) ==
 
<syntaxhighlight lang="csharp">
 
<syntaxhighlight lang="csharp">
 
using UnityEngine;
 
using UnityEngine;
Line 15: Line 42:
 
{
 
{
 
//distance at which objects can connect
 
//distance at which objects can connect
public float vRange = 30f;
+
public float Range = 50f;
 
//distance at which previews hover
 
//distance at which previews hover
public float vHoverDist = 5f;
+
public float HoverDist = 10f;
 
//tag for the position markers
 
//tag for the position markers
public string vTag = "handle";
+
public string Tag = "handle";
 
//currently selected part in the list
 
//currently selected part in the list
 
//change this from wherever to have the player select an item
 
//change this from wherever to have the player select an item
public int vSelected = -1;
+
public int Selected = -1;
 
//list of all prefabs
 
//list of all prefabs
 
public List<Part> Prefabs = new List<Part>();
 
public List<Part> Prefabs = new List<Part>();
Line 32: Line 59:
 
List<GameObject> Handles = new List<GameObject>();
 
List<GameObject> Handles = new List<GameObject>();
 
//currently active handle
 
//currently active handle
int vSelectedHandle = 0;
+
int SelectedHandle = 0;
 
//just a position holder
 
//just a position holder
 
Vector3 p;
 
Vector3 p;
Line 52: Line 79:
 
CheckSelection();
 
CheckSelection();
 
//if any item is "active"
 
//if any item is "active"
if(vSelected != -1)
+
if(Selected != -1)
 
{
 
{
 
//check if anything was hit
 
//check if anything was hit
if(Physics.Raycast(Camera.main.ScreenPointToRay(new Vector3((Screen.width / 2), (Screen.height / 2), 0)), out hit, vRange))
+
if(Physics.Raycast(Camera.main.ScreenPointToRay(new Vector3((Screen.width / 2), (Screen.height / 2), 0)), out hit, Range))
 
{
 
{
 
//enable preview
 
//enable preview
 
EnableSelected();
 
EnableSelected();
 
//check hit object for its tag
 
//check hit object for its tag
if(hit.transform.tag == vTag)
+
if(hit.transform.tag == Tag)
 
{
 
{
 
//find position
 
//find position
p = Handles[vSelectedHandle].transform.position - Preview.transform.position;
+
p = Handles[SelectedHandle].transform.position - Preview.transform.position;
 
//move preview into position
 
//move preview into position
 
Preview.transform.position = hit.transform.position - p;
 
Preview.transform.position = hit.transform.position - p;
Line 73: Line 100:
 
//enable preview
 
//enable preview
 
EnableSelected();
 
EnableSelected();
Preview.transform.position = Camera.main.transform.position+(Camera.main.transform.forward*vHoverDist);
+
Preview.transform.position = Camera.main.transform.position+(Camera.main.transform.forward*HoverDist);
 
}
 
}
 
// rotating
 
// rotating
Line 95: Line 122:
 
{
 
{
 
//instantiate if no preview is present
 
//instantiate if no preview is present
Preview = Instantiate(Prefabs[vSelected].Preview,Camera.main.transform.position+(Camera.main.transform.forward*vHoverDist), new Quaternion(0,0,0,0)) as GameObject;
+
Preview = Instantiate(Prefabs[Selected].Preview,Camera.main.transform.position+(Camera.main.transform.forward*HoverDist), new Quaternion(0,0,0,0)) as GameObject;
 
FindHandles(Preview);
 
FindHandles(Preview);
 
}
 
}
else if(Preview.transform.tag != Prefabs[vSelected].Preview.transform.tag)
+
else if(Preview.transform.tag != Prefabs[Selected].Preview.transform.tag)
 
{
 
{
 
//if wrong preview is present,  
 
//if wrong preview is present,  
 
//delete, then instantiate correct one
 
//delete, then instantiate correct one
 
Destroy(Preview);
 
Destroy(Preview);
Preview = Instantiate(Prefabs[vSelected].Preview,Camera.main.transform.position+(Camera.main.transform.forward*vHoverDist), new Quaternion(0,0,0,0)) as GameObject;
+
Preview = Instantiate(Prefabs[Selected].Preview,Camera.main.transform.position+(Camera.main.transform.forward*HoverDist), new Quaternion(0,0,0,0)) as GameObject;
 
FindHandles(Preview);
 
FindHandles(Preview);
 
}
 
}
Line 109: Line 136:
 
{
 
{
 
//else just move the preview
 
//else just move the preview
Preview.transform.position = Camera.main.transform.position+(Camera.main.transform.forward*vHoverDist);
+
Preview.transform.position = Camera.main.transform.position+(Camera.main.transform.forward*HoverDist);
 
}
 
}
 
}
 
}
Line 117: Line 144:
 
if(Input.GetMouseButtonUp(0))
 
if(Input.GetMouseButtonUp(0))
 
{
 
{
Instantiate(Prefabs[vSelected].Prefab, Preview.transform.position, Preview.transform.rotation);
+
Instantiate(Prefabs[Selected].Prefab, Preview.transform.position, Preview.transform.rotation);
 
}
 
}
 
}
 
}
Line 143: Line 170:
 
if(Handles.Count > 0)
 
if(Handles.Count > 0)
 
{
 
{
vSelectedHandle++;
+
SelectedHandle++;
if(vSelectedHandle >= Handles.Count)
+
if(SelectedHandle >= Handles.Count)
 
{
 
{
vSelectedHandle = 0;
+
SelectedHandle = 0;
 
}
 
}
 
}
 
}
Line 157: Line 184:
 
foreach(Transform c in Preview.transform)
 
foreach(Transform c in Preview.transform)
 
{
 
{
if(c.tag == vTag)
+
if(c.tag == Tag)
 
{
 
{
 
Handles.Add(c.gameObject);
 
Handles.Add(c.gameObject);
Line 171: Line 198:
 
if(Input.GetKeyDown ("1"))
 
if(Input.GetKeyDown ("1"))
 
{
 
{
if(vSelected != 0)
+
if(Selected != 0)
{vSelected = 0;}
+
{Selected = 0;}
 
else
 
else
{vSelected = -1;}
+
{Selected = -1;}
vSelectedHandle = 0;
+
SelectedHandle = 0;
 
}
 
}
 
else if(Input.GetKeyDown ("2"))
 
else if(Input.GetKeyDown ("2"))
 
{
 
{
if(vSelected != 1)
+
if(Selected != 1)
{vSelected = 1;}
+
{Selected = 1;}
 
else
 
else
{vSelected = -1;}
+
{Selected = -1;}
vSelectedHandle = 0;
+
SelectedHandle = 0;
 
}
 
}
 
}
 
}
 
}
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
== History ==
 +
 +
* 12 March 2016 - Release

Revision as of 21:11, 12 March 2016

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.

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 with
	[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 hit object for its tag
				if(hit.transform.tag == Tag)
				{
					//find 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
			{
				//enable preview
				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 placer to confirm placing the prefab 
	void AwaitPlacement()
	{
		if(Input.GetMouseButtonUp(0))
		{
			Instantiate(Prefabs[Selected].Prefab, Preview.transform.position, Preview.transform.rotation);
		}
	}
	//waits forplayer 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