Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Snap Geometry to a terrain object

Discussion in 'Scripting' started by Sajid, Feb 23, 2015.

  1. Sajid

    Sajid

    Joined:
    Mar 12, 2011
    Posts:
    199
    Hey all,

    I'm wondering how to go about instantiating an object at the position of the mouse in such a way that it snaps to the terrain and lays flat.

    I can already instantiate and place an object at the mouse position, but for example, if I instantiate a cube at the mouse position, and the terrain under the mouse is not flat, the cube will clip because it's only taking into consideration the mouse position.

    I'm thinking maybe to take the rotation of the terrain under the mouse and put that on the object I'm instantiating, but I don't know if that's a good way to go about it.
     
  2. Glurth

    Glurth

    Joined:
    Dec 29, 2014
    Posts:
    109
    Don't forget the fact that your cube covers and AREA, while you mouse click is only a point. Unless you place the box at the highest point under it's entire bottom surface, it will be partially underground. (unless you happened to click on a "peak")
     
  3. Strategos

    Strategos

    Joined:
    Aug 24, 2012
    Posts:
    255
  4. Sajid

    Sajid

    Joined:
    Mar 12, 2011
    Posts:
    199
    I tried this, and it seems to work, except that it always places the cube in the center of the floor instead of under my mouse position.

    It seems like what is happening is that my mouse position is just telling the cube which object to get it's normal from. What I really want is for the normal to be calculated in the area specifically under my mouse. So if I have my mouse over (1,1.5,0), I want the normal to be calculated underneath. Here is the code in question:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4. public class item_brick : MonoBehaviour
    5. {
    6.         public Sprite sprite;
    7.         public string itemName;
    8.         private RaycastHit rayHit;
    9.         private RaycastHit normalHit;
    10.         private bool isTrackingMouse;
    11.         private GameObject levelControl;
    12.    
    13.    
    14.         // Use this for initialization
    15.         void Start ()
    16.         {
    17.                 levelControl = GameObject.FindGameObjectWithTag ("Level Control");
    18.        
    19.                 isTrackingMouse = true;
    20.         }
    21.    
    22.         // Update is called once per frame
    23.         void Update ()
    24.         {
    25.        
    26.        
    27.                 if (levelControl.GetComponent<getMenu> ().menuOpen == false) {
    28.                         if (isTrackingMouse) {
    29.                                 Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out rayHit);
    30.                                 Vector3 offset = rayHit.normal;
    31.                                 Debug.Log (offset);
    32.                                 transform.position = offset;
    33.                
    34.                
    35.                         }
    36.                 }
    37.        
    38.                 if (Input.GetKeyDown (KeyCode.F)) {
    39.                         gameObject.tag = "Brick_Placed";
    40.                         isTrackingMouse = false;
    41.                 }
    42.        
    43.         }
    44. }
    45.  
     
  5. Glurth

    Glurth

    Joined:
    Dec 29, 2014
    Posts:
    109
    Strategos was talking about using the normal to set the ROTATION of your object, so it sits flush with the floor. Looks like you are using it to set your position, which doesn't really make sense (values will all be magnitude 1 since they are normalized).

    Note: His suggestion assumes that the floor is smooth enough under the surface of the cube.

    You probably want to set your offset with something like (un-complied):

    Code (CSharp):
    1. Vector3 offset= rayHit.position;  //might need to modify this to find the highest position around the hit point, based on the cube size
    2. Vector3 tilt= rayHit.normal; //might want to use the normal from the highest point you find, under the cube, rather than the hit point
    3. transform.position= offset;
    4. transform.rotation=Quaternion.LookRotation(tilt);