Search Unity

Building Placement Bug

Discussion in 'Scripting' started by Aspiron94, Dec 24, 2019.

  1. Aspiron94

    Aspiron94

    Joined:
    Nov 2, 2016
    Posts:
    12
    Hi everyone,

    I'm encountering the following problem.
    I have a button that instantiates a prefab to the current mouse position and can rotate with the mouse scroll wheel. But when I press the button to instantiate it, the prefab does something weird.
    I have recorded a video about this problem and I hope there is someone here that can explain me why that I have this problem and how to solve it?

    The link to the video:
    https://drive.google.com/open?id=1elWyqspLpzizAx6eDlALUNtKww0UuyPi

    The code that I use for placing objects:

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class BuildPrefab : MonoBehaviour
    7. {
    8.     //GAMEOBJECTS
    9.     public GameObject placeableObjectPrefab;
    10.     public GameObject currentPlaceableObject;
    11.  
    12.     //FLOATS
    13.     private float mouseWheelRotation;
    14.     public float RotationAmount = 45f;
    15.  
    16.     //BOOLEANS
    17.     public bool isClicked = false;
    18.  
    19.     public void Select()
    20.     {
    21.         isClicked = true;
    22.     }
    23.  
    24.     private void Update()
    25.     {
    26.         InstantiatePrefab();
    27.  
    28.         if (currentPlaceableObject != null)
    29.         {
    30.             MoveCurrentObjectToMouse();
    31.             RotateFromMouseWheel();
    32.             ReleaseIfClicked();
    33.         }
    34.     }
    35.  
    36.     private void InstantiatePrefab()
    37.     {
    38.         if (isClicked)
    39.         {
    40.             if (Input.GetMouseButtonDown(1))
    41.             {
    42.                 currentPlaceableObject = null;
    43.                 isClicked = false;
    44.             }
    45.             else if (!Input.GetMouseButtonDown(1))
    46.             {
    47.                 currentPlaceableObject = Instantiate(placeableObjectPrefab);
    48.             }
    49.         }
    50.     }
    51.  
    52.     private void MoveCurrentObjectToMouse()
    53.     {
    54.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    55.  
    56.         RaycastHit hit;
    57.         if (Physics.Raycast(ray, out hit))
    58.         {
    59.             currentPlaceableObject.transform.position = hit.point;
    60.             currentPlaceableObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
    61.         }
    62.     }
    63.  
    64.     private void RotateFromMouseWheel()
    65.     {
    66.         Debug.Log(Input.mouseScrollDelta);
    67.         mouseWheelRotation += Input.mouseScrollDelta.y;
    68.         currentPlaceableObject.transform.Rotate(Vector3.up, mouseWheelRotation * RotationAmount);
    69.     }
    70.  
    71.     private void ReleaseIfClicked()
    72.     {
    73.         if (Input.GetMouseButtonDown(0))
    74.             currentPlaceableObject = null;
    75.  
    76.         isClicked = false;
    77.     }
    78. }
     
  2. lordconstant

    lordconstant

    Joined:
    Jul 4, 2013
    Posts:
    389
    Your issue is that the raycast is hitting the object you just tried to place.
     
  3. Aspiron94

    Aspiron94

    Joined:
    Nov 2, 2016
    Posts:
    12
    So how do I fix this? I'm still learning.
     
  4. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    I did not download and watch the videos (it is probably better to upload them on a well-known portal), but assuming @lordconstant got it on point, then you have to ignore the object you want to place.

    When there's no more logic involved, you can choose either of those:
    1) Remove/disable the colliders of the object you want to place (or the preview object) and ensure you add/enable them afterwards.
    2) Assign a specific layer and make sure that layer is ignored by your raycast (there are overloads of the raycasting functions that take layer masks). There is already a pre-defined layer for that: the IgnoreRaycast layer. When you use that one, you won't need to change the raycast at all, because that layer is already ignored by that API.
     
  5. Aspiron94

    Aspiron94

    Joined:
    Nov 2, 2016
    Posts:
    12
    Thanks for answering, after somewhile I have finally found the solution to this!
    I've wrote this line of code "currentPlaceableObject.layer = 11;" in the wrong place.
    The wright place is that works for me:

    Code (CSharp):
    1. private void ReleaseIfClicked()
    2.     {
    3.         if (Input.GetMouseButtonDown(0))
    4.         {
    5.             currentPlaceableObject.layer = 11;
    6.             currentPlaceableObject = null;
    7.         }
    8.  
    9.         isClicked = false;
    10.     }
     
    Last edited: Dec 28, 2019