Making Building Placement Buildings rotateable

Hey! So I have this script where you can place buildings and stuff but im not sure how to make it so when your trying to place it you can rotate it on a 90-degree scale so from 90 to 180 to 270 to 360. How can I do this? Here is my code: PS This is my BuildingManager script. If you need my BuildingList, BuildingColision or even the ButtonGUI just tell me :slight_smile:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// Build manager.
/// 
/// This Script is attached to a empty GameObject
/// </summary>

[System.Serializable]
public class Snapping
{
	public bool snappingEnabled = true;
    public float snapRadius = 2.0f;
    public float snapMagin = 0.0f;
    public SnapSides snapSides;
}

[System.Serializable]
public struct SnapSides
{
    // based on objects facing direction
    public bool left, right, top, bottom, front, back;
}

public class BuildManager: MonoBehaviour 
{
	public int SelectedBuilding;
	private int LastSelectedBuilding;
	public GameObject[] Building;
	
	public List<BuildingList> buildings = new List<BuildingList>();
	
	public string TerrainCollisionTag;

    private bool ghostOn = false;
    private GameObject ghost;
    private BuildingCollision ghostCollision;

	private bool isFlat;
	public float maxSlopeHigh = 5f;

    public bool isBuildingEnabled { get; private set; }

    // Unused until fully implemented
   public Snapping snapping = new Snapping();

    void Start()
	{
		LastSelectedBuilding = SelectedBuilding;
        isBuildingEnabled = false;

    }

    public void ActivateBuildingmode()
    {
        isBuildingEnabled = true;
    }

    public void DeactivateBuildingmode()
    {
        isBuildingEnabled = false;
    }

    public void SelectBuilding(int id)
    {
        if (id < Building.Length && id >= 0)
        {
            LastSelectedBuilding = SelectedBuilding;
            SelectedBuilding = id;
        }
    }

    void Update()
	{
        if (!isBuildingEnabled)
        {
            if (ghost != null)
            {
                Destroy(ghost);
                ghostOn = false;
            }
                
            return;
        }
            

		Ray ray;
		RaycastHit[] hit;
		ray = Camera.main.ScreenPointToRay(Input.mousePosition);
		hit = Physics.RaycastAll(ray, Mathf.Infinity);
	
		for (int i = 0; i < hit.Length; i++)
		{
            if (hit*.collider.tag == TerrainCollisionTag)*
  •  	{*
    

if (SelectedBuilding != LastSelectedBuilding && ghost != null)

  •  		{*
    
  •  			Destroy(ghost);*
    
  •  			ghostOn = false;*
    
  •  			LastSelectedBuilding = SelectedBuilding;*
    
  •  			break;*
    
  •  		}*
    
  •  		if (!ghostOn)*
    
  •  		{*
    
  •  			ghost = (GameObject)Instantiate(Building[SelectedBuilding],* 
    

_ new Vector3(hit*.point.x,_
_ hit.point.y,
hit.point.z),
Quaternion.identity);*_

ghost.name = ghost.name.Replace(“(Clone)”, “(Ghost)”);
ghost.layer = 2; //ignore raycast layer

ghostCollision = ghost.AddComponent();

* ghostOn = true; *
* }*

* if (ghost != null)*
* {*
if (Input.GetMouseButtonDown(0) && !ghostCollision.Collided() && isFlat)
{
BuildingList bl = new BuildingList();

DestroyImmediate(ghost);

bl.buildingGameObject = (GameObject)Instantiate(Building[SelectedBuilding],
new Vector3(hit*.point.x,*
hit*.point.y + Building[SelectedBuilding].GetComponent().transform.localScale.y / 2,*
hit*.point.z),*
Quaternion.identity);

string s = bl.buildingGameObject.name.Replace(“(Clone)”, “”);
bl.buildingGameObject.name = s;
bl.buildingName = s;
bl.buildingGameObject.AddComponent();

buildings.Add(bl);

ghostOn = false;

DeactivateBuildingmode();

break;
}

Vector3 ghostTargetPos = new Vector3(
hit*.point.x,*
hit*.point.y + Building[SelectedBuilding].GetComponent().transform.localScale.y / 2,*
hit*.point.z);*

ghost.transform.position = ghostTargetPos;

* isFlat = GroundFlat();*

* if (ghostCollision.Collided() || !isFlat)*
* {*
* ghost.GetComponent().material.CopyPropertiesFromMaterial(Building[SelectedBuilding].GetComponent().sharedMaterial);*
* ghost.GetComponent().material.color = new Color(*
* 1f,*
* 0f,*
* 0f,*
* 0.6f);*
* } *
* else if (!ghostCollision.Collided() && isFlat)*
* {*
* ghost.GetComponent().material.CopyPropertiesFromMaterial(Building[SelectedBuilding].GetComponent().sharedMaterial);*
* ghost.GetComponent().material.color = new Color(*
* 0f,*
* 1f,*
* 0f,*
* 0.6f);*
* }*

* }*
* } *
* }*
* }*

private bool GroundFlat()
{
RaycastHit[] buildingSlopeHitULAll;
RaycastHit[] buildingSlopeHitURAll;
RaycastHit[] buildingSlopeHitDLAll;
RaycastHit[] buildingSlopeHitDRAll;
RaycastHit[] buildingSlopeHitMAll;

buildingSlopeHitULAll = Physics.RaycastAll(new Vector3(
ghost.GetComponent().transform.position.x - ghost.transform.localScale.x / 2,
ghost.GetComponent().transform.position.y + Building[SelectedBuilding].GetComponent().transform.localScale.y / 2,
ghost.GetComponent().transform.position.z - ghost.transform.localScale.z / 2),
Vector3.down, Mathf.Infinity);

buildingSlopeHitURAll = Physics.RaycastAll(new Vector3(
ghost.GetComponent().transform.position.x + ghost.transform.localScale.x / 2,
ghost.GetComponent().transform.position.y + Building[SelectedBuilding].GetComponent().transform.localScale.y / 2,
ghost.GetComponent().transform.position.z - ghost.transform.localScale.z / 2),
Vector3.down, Mathf.Infinity);

buildingSlopeHitDLAll = Physics.RaycastAll(new Vector3(
ghost.GetComponent().transform.position.x - ghost.transform.localScale.x / 2,
ghost.GetComponent().transform.position.y + Building[SelectedBuilding].GetComponent().transform.localScale.y / 2,
ghost.GetComponent().transform.position.z + ghost.transform.localScale.z / 2),
Vector3.down, Mathf.Infinity);

buildingSlopeHitDRAll = Physics.RaycastAll(new Vector3(
ghost.GetComponent().transform.position.x + ghost.transform.localScale.x / 2,
ghost.GetComponent().transform.position.y + Building[SelectedBuilding].GetComponent().transform.localScale.y / 2,
ghost.GetComponent().transform.position.z + ghost.transform.localScale.z / 2),
Vector3.down, Mathf.Infinity);

buildingSlopeHitMAll = Physics.RaycastAll(new Vector3(
ghost.GetComponent().transform.position.x,
ghost.GetComponent().transform.position.y + Building[SelectedBuilding].GetComponent().transform.localScale.y / 2,
ghost.GetComponent().transform.position.z),
Vector3.down, Mathf.Infinity);

RaycastHit hitUL = new RaycastHit(), hitUR = new RaycastHit(), hitDL = new RaycastHit(), hitDR = new RaycastHit(), hitM = new RaycastHit();

foreach (RaycastHit hit in buildingSlopeHitULAll)
{
if (hit.collider.tag == TerrainCollisionTag)
{
hitUL = hit;
break;
}
}
foreach (RaycastHit hit in buildingSlopeHitURAll)
{
if (hit.collider.tag == TerrainCollisionTag)
{
hitUR = hit;
break;
}
}
foreach (RaycastHit hit in buildingSlopeHitDLAll)
{
if (hit.collider.tag == TerrainCollisionTag)
{
hitDL = hit;
break;
}
}
foreach (RaycastHit hit in buildingSlopeHitDRAll)
{
if (hit.collider.tag == TerrainCollisionTag)
{
hitDR = hit;
break;
}
}
foreach (RaycastHit hit in buildingSlopeHitMAll)
{
if (hit.collider.tag == TerrainCollisionTag)
{
hitM = hit;
break;
}
}

if ((buildingSlopeHitULAll.Length > 0 ? hitUL.collider != null : false) &&
(buildingSlopeHitURAll.Length > 0 ? hitUR.collider != null : false) &&
(buildingSlopeHitDLAll.Length > 0 ? hitDL.collider != null : false) &&
(buildingSlopeHitDRAll.Length > 0 ? hitDR.collider != null : false) &&
(buildingSlopeHitMAll.Length > 0 ? hitM.collider != null : false))
{

if (HitDistanceSmallerEqual(hitUL, maxSlopeHigh) &&
HitDistanceSmallerEqual(hitUR, maxSlopeHigh) &&
HitDistanceSmallerEqual(hitDL, maxSlopeHigh) &&
HitDistanceSmallerEqual(hitDR, maxSlopeHigh) &&
HitDistanceSmallerEqual(hitM, maxSlopeHigh))
{
return true;
}
else
return false;
}
else
return false;
}

private bool ContainsTag(RaycastHit[] hitArr, string tag)
{
foreach (RaycastHit h in hitArr)
if (h.collider.tag == tag)
return true;

return false;
}

private bool ContainsTag(RaycastHit[] hitArr, string tag, out RaycastHit correctHit)
{
foreach (RaycastHit h in hitArr)
if (h.collider.tag == tag)
{
correctHit = h;
return true;
}

correctHit = new RaycastHit();
return false;
}

private bool HitDistanceSmallerEqual(RaycastHit hit, float val)
{
if (hit.distance - (ghost.transform.localScale.y) <= val)
return true;

return false;
}

static void ClearConsole()
{
// This simply does “LogEntries.Clear()” the long way:
var logEntries = System.Type.GetType(“UnityEditorInternal.LogEntries,UnityEditor.dll”);
var clearMethod = logEntries.GetMethod(“Clear”, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
clearMethod.Invoke(null, null);
}
}

Well, why not add Quaternion.Euler with params of transform.rotation. + 90? Then just make check for if(angle is 360){ set rotation to 0 } and assign it?

Hi! Leerow is on the right track. Your instantiate code:

ghost = (GameObject)Instantiate(Building[SelectedBuilding], 
                     new Vector3(hit*.point.x,*

hit*.point.y,*
hit*.point.z),*
Quaternion.identity);
Instead of using Quaternion.identity, use the correct rotational Quaternion :slight_smile:

Store a quaternion previewRotation for your building preview (I’m assuming that’s what ghost is), when the user hits whatever input for rotation:

if(input)
    previewRotation = Quaternion.Euler(previewRotation.eulerAngles + new Vector3(0, 90, 0));

Then when you instantiate the final version of the building instead of using Quaternion.identity use previewRotation; then I assume you wouldn’t want the preview to persist through different building placements so reset previewRotation to Quaternion.identity.

This is quite easy, the solution I would use is something like this:

float objectRotation;

void update(){
    if(Input.getButtonDown("MyRotateClockwisebutton")){
        objectRotation = objectRotation - 90;
    }
}

Instantiate code

Instantiate(MyPrefab, myRotation, Quaternion.Euler(new Vector3(0, objectRotation, 0)));