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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Forcing an object to stay grounded when attached to mouse cursor.

Discussion in 'Scripting' started by CarltonSmith, Feb 18, 2014.

  1. CarltonSmith

    CarltonSmith

    Joined:
    Jan 19, 2014
    Posts:
    21
    Ok bare with me. I have a simple plane for a floor. A first person character controller. And a cube. The cube has this script on it.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ObjectFollowMouse : MonoBehaviour
    5. {
    6.     public float depth = 10;
    7.     public float speed = 10;
    8.    
    9.     void Start ()
    10.     {
    11.         Screen.showCursor = false;
    12.     }
    13.    
    14.     // Update is called once per frame
    15.     void Update ()
    16.     {
    17.         float rotateSpeed = speed * Time.deltaTime;
    18.         Vector2 mousePos = Input.mousePosition;
    19.  
    20.         Vector3 wantedPos = Camera.main.ScreenToWorldPoint (new Vector3 (mousePos.x, mousePos.y, depth));
    21.         transform.position = wantedPos;
    22.         if(Input.GetKey(KeyCode.RightArrow))
    23.         {
    24.             transform.Rotate(Vector3.up, rotateSpeed);
    25.         }
    26.         if(Input.GetKey(KeyCode.LeftArrow))
    27.         {
    28.             transform.Rotate(Vector3.up, - rotateSpeed);
    29.         }
    30.     }
    31.  
    32. }
    Which basically makes the object (the cube) stay in the middle of the screen and rotate when the arrow keys are pressed.
    What i want to do is ground the object to the floor from a certain distance away to a certain distance away (not too close, not too far), without the object being able to pass through the floor, or leave it. I cant figure out how to do that so far. At the moment it literally does as expected which is follow where the mouse position would be.

    Its basically so i can position the object in game and "click" and the object places itself at that position which im not up to yet.
    Sorry if it doesnt make sense what i am trying to do. Please ask and i will explain it further.
     
  2. CarltonSmith

    CarltonSmith

    Joined:
    Jan 19, 2014
    Posts:
    21
    Sorry to bump but i still cant work this out at all. Maybe something where i snap to a small grid on the ground but i cant work out how to do that either.
     
  3. PJRM

    PJRM

    Joined:
    Mar 4, 2013
    Posts:
    303
    I don't get it.
    May I ask a PrintScreen example of your scene? Maybe I understand better looking at your scene situation.
     
  4. CarltonSmith

    CarltonSmith

    Joined:
    Jan 19, 2014
    Posts:
    21
    Hi, thanks for the interest. I have attached two pics but the best way to describe what i want to achieve would be by linking a vid. Here is what my project is currently doing (as well, the cube spins out of control which i also do not want).

    $pic1.jpg

    $pic2.jpg

    What i actually want is to place objects in a similar fashion to the game "Space Engineers".

    Skip to 28 seconds to see exactly what i mean
    http://www.youtube.com/watch?v=oXL4X44f0zo

    In hindsight i think i should have posted this video in my first thread. I apologise.
     
  5. PJRM

    PJRM

    Joined:
    Mar 4, 2013
    Posts:
    303
    Basic you need is a bool variable to say when it can be drag or not.
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. using System.Collections;
    4.  
    5.  
    6.  
    7. public class ObjectFollowMouse : MonoBehaviour  {
    8.   public float depth = 10;
    9.   public float speed = 10;
    10.   public bool canBeDrag = true;
    11.  
    12.   void Start () {
    13.     Screen.showCursor = false;
    14.   }
    15.  
    16.   void Update () {
    17.     float rotateSpeed = speed * Time.deltaTime;
    18.  
    19.     Vector2 mousePos = Input.mousePosition;
    20.     Vector3 wantedPos = Camera.main.ScreenToWorldPoint (new Vector3 (mousePos.x, mousePos.y, depth));
    21.  
    22.     if (canBeDrag)
    23.       transform.position = wantedPos;
    24.  
    25.     if(Input.GetMouseButtonDown(0)) {
    26.       canBeDrag = false
    27.     }
    28.     if(Input.GetKey(KeyCode.RightArrow)) {
    29.       transform.Rotate(Vector3.up, rotateSpeed);
    30.     }
    31.     if(Input.GetKey(KeyCode.LeftArrow)) {
    32.       transform.Rotate(Vector3.up, - rotateSpeed);
    33.     }
    34.   }
    35. }
    this looks like RTS which we build structures.
    If this is not what you need, tell me! then we look for something else.
    Best regards,
    PJRM - Plínio J.
     
  6. jackmott

    jackmott

    Joined:
    Jan 5, 2014
    Posts:
    167
    additionally he may need to cast a ray into the terrain to get the point where that ray intersects the terrain to place the object correctly. I don't think depth will always work unless he is keeping everything centered.

    So look into RayCast, RayCatHit, and then just translate the object in the Vector3.up direction to make it higher or lower than the terrain
     
  7. CarltonSmith

    CarltonSmith

    Joined:
    Jan 19, 2014
    Posts:
    21
    Thanks for the replies. Unfortunately its not doing what i want it to. Basically i just want the block (which will be a prefab later on) to behave like the space engineers video. I was thinking i might need to do something with raycasts as the surface will not always be flat (although i have it on a plane now, i would like it on terrain eventually). The problem is i still dont understand what i would do with raycasting to make sure it stays grounded (i sort of understand raycasting from what i have read and seen, but not enough to just straight up use it in a script to the desired effect).
     
  8. PJRM

    PJRM

    Joined:
    Mar 4, 2013
    Posts:
    303
    Jackmott said that if your project ground is always Y=0, then you don't have to worry about raycast.
    In the case of the video, you can instantiate a new prefab in that position instead of releasing the object that is hold mouse.
     
  9. CarltonSmith

    CarltonSmith

    Joined:
    Jan 19, 2014
    Posts:
    21
    Yeah thats what i had in a previous version, something that instantiated a different prefab on mouseclick (although i couldnt get the prefab instantiated at the same position as the cube placeholder, that was a different issue) but i still dont have the desired result. 2 things missing really.

    1) The object is still not grounded, if i use y=0 i get strange results (as in it ignores it so im clearly not using it right). In general it does not behave like the space engineers demo at 28seconds.

    2) I wont always be using a flat surface. I do intend to use it on terrain so i also need to incorporate a way to work out whether the terrain is too steep to place the object or if its only a little bumpy, flatten the terrain appropriately but i fear that's over my head currently.

    I simply dont know how to use raycast well enough or object position to keep the object grounded when moving around the scene (again like the space engineers demo but at 28 seconds and in first person view instead of its third).