So I attempted this, and I ended up with a general mess, but the mess displayed a preview and the preview followed the cursor around and I even had it “build” single objects. But that wasn’t the goal. My idea was something similar to classic construction management games. I’ll post an image of what I wanted it to look like and what it turned into in a video. I’ve been working all last night and most of this morning and none of my labors have born any fruits…
Goal (Built in Editor):
End Result (Mucking around in Runtime):
Thanks in advance!
Edit: Didn’t find much on Google
Edit: And here’s some of my code:
public void GetBuildArea ()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 v;
v.x = selector.currentObject.transform.position.x;
v.y = 0;
v.z = selector.currentObject.transform.position.z;
ZoneStart = v;
}
if (Input.GetMouseButton(0))
{
Vector3 v = selector.currentObject.transform.position;
ZoneEnd = v;
RenderPreviewArea();
}
}
public void RenderPreviewArea ()
{
for (int x = (int)ZoneStart.x; x < (int)ZoneEnd.x; x++)
{
for (int z = (int)ZoneStart.y; x < (int)ZoneEnd.y; z++)
{
if (Physics.Raycast(new Vector3(x, 0, z), new Vector3(1, 0, 1), 0.65f))
{
PreviewHolder = (GameObject)Instantiate(selector.selectedPart, new Vector3(x, 0, z), Quaternion.identity);
PreviewHolder.name = string.Format("Preview Area at ({0}, 0, {1})", x, z);
BuiltPreview.Add(PreviewHolder);
}
}
}
}
If you could post the whole script, it would be easier, maybe you’re not calling the GetBuildArea() function in the update
I have multiple scripts working together, but I checked and that wasn’t the problem. I was just hoping some one could help me find a method in which to make this idea a reality. I understand C# and I know that my code doesn’t have any errors. All I’m looking for is how to make it, not how to fix somethting that doesn’t even do what I wanted it to do. My attempt was a joke to be honest, so a fresh look at this concept from someone else would be nice.
Thanks for your suggestion. Sadly that wasn’t the answer…
I have solved this problem!
always nice to know what it was in case someone else stumbles onto this thread in the future…
https://www.youtube.com/watch?v=Rur_aKPeaQw
I solved it with a for loop that instantiated a list of gameobjects then if the area in vector3 didn’t match the value of the previous update’s vector3 it would clear the list and destroy the gameobjects. I used getmousebuttondown to record the origin and getmousebutton to update the end point and the total area. It’s still a bit buggy but it works except for 1x1 or 2x1 or 2x2 blocks. If you want the source code you’ll have to wait, as I typed this on my phone
1 Like
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class BuildingManager : MonoBehaviour
{
public CameraController cameraScript;
public SelectionManager selector;
public CellManager cellScript;
public List<GameObject> BuildArea = new List<GameObject>();
public Vector3 TotalBuildArea;
public Vector3 PreviousBuildArea;
public Vector3 BuildAreaOrigin;
public Vector3 BuildAreaEnd;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (cameraScript.CurrentObject != null)
{
cellScript = cameraScript.CurrentObject.GetComponent<CellManager>();
GetBuildArea();
}
else
{
cellScript = null;
}
}
void GetBuildArea ()
{
if (Input.GetMouseButtonDown(0))
{
BuildAreaOrigin = cameraScript.CurrentObject.transform.position;
}
if (Input.GetMouseButton(0))
{
BuildAreaEnd = cameraScript.CurrentObject.transform.position;
}
ClearBuildArea();
RenderBuildArea();
if (Input.GetMouseButtonUp(0))
{
BuildAreaEnd = cameraScript.CurrentObject.transform.position;
RenderBuildArea();
}
}
void RenderBuildArea ()
{
TotalBuildArea = new Vector3(BuildAreaEnd.x - BuildAreaOrigin.x, 0, BuildAreaEnd.z - BuildAreaOrigin.z);
if (TotalBuildArea.x > 0 && TotalBuildArea.z > 0)
{
for (int x = 0; x <= TotalBuildArea.x; x++)
{
for (int z = 0; z <= TotalBuildArea.z; z++)
{
GameObject temp = (GameObject)Instantiate(selector.SelectedPart, new Vector3(x + BuildAreaOrigin.x, 0, z + BuildAreaOrigin.z), Quaternion.identity);
temp.name = string.Format("Preview #{0}", x+z);
temp.transform.parent = this.transform;
BuildArea.Add(temp);
}
}
}
else if (TotalBuildArea.x < 0 && TotalBuildArea.z < 0)
{
for (int x = 0; x >= TotalBuildArea.x; x--)
{
for (int z = 0; z >= TotalBuildArea.z; z--)
{
GameObject temp = (GameObject)Instantiate(selector.SelectedPart, new Vector3(x + BuildAreaOrigin.x, 0, z + BuildAreaOrigin.z), Quaternion.identity);
temp.name = string.Format("Preview #{0}", x+z);
temp.transform.parent = this.transform;
BuildArea.Add(temp);
}
}
}
else if (TotalBuildArea.x > 0 && TotalBuildArea.z < 0)
{
for (int x = 0; x <= TotalBuildArea.x; x++)
{
for (int z = 0; z >= TotalBuildArea.z; z--)
{
GameObject temp = (GameObject)Instantiate(selector.SelectedPart, new Vector3(x + BuildAreaOrigin.x, 0, z + BuildAreaOrigin.z), Quaternion.identity);
temp.name = string.Format("Preview #{0}", x+z);
temp.transform.parent = this.transform;
BuildArea.Add(temp);
}
}
}
else if (TotalBuildArea.x < 0 && TotalBuildArea.z > 0)
{
for (int x = 0; x >= TotalBuildArea.x; x--)
{
for (int z = 0; z <= TotalBuildArea.z; z++)
{
GameObject temp = (GameObject)Instantiate(selector.SelectedPart, new Vector3(x + BuildAreaOrigin.x, 0, z + BuildAreaOrigin.z), Quaternion.identity);
temp.name = string.Format("Preview #{0}", x+z);
temp.transform.parent = this.transform;
BuildArea.Add(temp);
}
}
}
}
void ClearBuildArea ()
{
foreach( GameObject g in BuildArea ) {
Destroy(g);
}
BuildArea.Clear();
}
}
There are some slight issues, as it won’t build 1x1 or 2x1 foundations… Anyone?
So, I found the 1 x 1 and 1 x 2 problem, you substract the end, and the origin positions, so you have an area 1 row or column less than it is, this is clearly seeable in the video too, so, if you have a 3x3 area, then let’s say that the beginning is at (0,0) and your end is at (2,2) so your calculated width is 2-0 = 2 and your height is 2-0 = 2, this means that when you want a 1x1 area, then your beginning and end is at the same position so the calculated width and height is 0, so you need to add 1 to that value. Sorry for the ginormous answer, but i hope i helped 
Thanks! It works now.
Had to change:
TotalBuildArea.x<0&& TotalBuildArea.z>0
To:
TotalBuildArea.x <= 0 && TotalBuildArea.z >= 0
I have a new problem. Now that I can place multiple foundations, I’d like to place walls on the foundation in single lines. Also foundations can overlap so that needs fixing. When I get home I’ll post my code, but I’m looking for help nonetheless. Thanks!
You mean, you want to place walls on the outside of the selected area, or place walls in a single line at a time?
I want to place walls in a single line along the foundation. I tried this earlier but the walls never showed.
GameObject CornerPiece;
GameObject Wall;
for (var x = 0; x < Foundations.GetDimension[0];x++) {
for (var y = 0; y < Foundations.GetDimension[1];y++) {
if (x == 0 && y == 0) {
GameObject.Instantiate(CornerPiece, Foundations[x,y] Vector3.up, Quaternion.identity);
} else if(... //more corners
//after the corners
} else {
GameObject.Instantiate(Wall, Foundations[x,y] + Vector3.up, Quaternion.identity);
}
}
}
I’m not sure, that this code works, but right now i can’t test it. The only problem that i know is that it doesn’t rotate the tiles, but when you assign the instantiated object to a variable (GameObject object = (GameObject)GameObject.Instantiate(…))
and then you rotate it somehow, it should work
Thanks! I’ll test it right away when I get home.