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

Controlling object's Y-position using the Y-position of the mouse.

Discussion in 'Scripting' started by Retruate, Oct 30, 2015.

  1. Retruate

    Retruate

    Joined:
    Jul 5, 2014
    Posts:
    111
    Controlling object's location via Input.mousePosition

    I've been using Unity for quite a while now, but I'd still consider myself a beginner, so I'm sorry if this is a beginner question.

    Anyway, I'm attempting to create a Pong styled game using Unity 2D and Unity's quad meshes. I want to move the Player (the bar) by having the Player directly follow the Y position of the mouse, up or down. In order to move the Player, I have a C# script (see below) that controls the Player by multiplying the Input.GetAxis ("Mouse Y") value by a float called Player Speed and then sets it to the Rigidbody 2D's velocity Y value under a new Vector 2. So far, this has worked fairly well, except the Player eventually gets disproportionate to the mouse position, because Player Speed is always either too fast or too slow. I think the way to get my desired effect, would be to use Input.mousePostion (http://docs.unity3d.com/ScriptReference/Input-mousePosition.html), but I'm not sure if so and I'm not sure how.

    Here's the code I'm using right now:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MoveVertically : MonoBehaviour {
    5.  
    6.  
    7. public float PlayerSpeed;
    8.  
    9. private float mouseY;
    10. private Rigidbody2D body2d;
    11.  
    12.  
    13. void Start () {
    14.  
    15. //Speed at which the player moves vertically.
    16. PlayerSpeed = 17;
    17.  
    18. body2d = GetComponent<Rigidbody2D> ();
    19. }
    20.  
    21.  
    22. void Update () {
    23.  
    24. mouseY = Input.GetAxis ("Mouse Y");
    25.  
    26. //3.5 = the point where the top edge of the player is touching the screen;
    27. //Stops all positive movement by making mouseY = 0 when player is at top of screen.
    28. if (gameObject.transform.position.y >= 3.5) {
    29. transform.position = new Vector3 (transform.position.x, 3.5f, transform.position.z);
    30. if (mouseY >= 0){
    31. mouseY = 0;
    32. }
    33. }
    34.  
    35. //-3.5 = the point where the bottom edge of the player is touching the screen;
    36. //Stops all negative movement by making mouseY = 0 when player is at top of screen.
    37. if (gameObject.transform.position.y <= -3.5) {
    38. transform.position = new Vector3 (transform.position.x, -3.5f, transform.position.z);
    39. if (mouseY <= 0){
    40. mouseY = 0;
    41. }
    42. }
    43.  
    44. //Vertically moves the player relative to the mouseY value by the PlayerSpeed.
    45. body2d.velocity = new Vector2 (0, mouseY * PlayerSpeed);
    46. }
    47.  
    48.  
    49. }
    Any help on how to fix my issue is appreciated. Thanks!

    (The attached file is a screenshot.)
     

    Attached Files:

  2. UltiGamer835

    UltiGamer835

    Joined:
    Jun 5, 2013
    Posts:
    8
    I made another script that you could use for reference I guess. The only concern you may have is that it doesn't use a rigidbody, and that the Player's position might not be in the exact y position of the cursor (or mouse) unless the game is played on full screen. Anyhow, I hope I've helped you out. :)

    Code (CSharp):
    1. public float PlayerSpeed;
    2.  
    3.     float playerPosition;
    4.    
    5.  
    6.     void Update()
    7.     {
    8.         //Finds the position you want the Player to move to, relative to your screen resolution.
    9.         //Keep in mind that the larger the player speed is, the slower the character will go.
    10.         playerPosition = Input.mousePosition.y / PlayerSpeed;
    11.  
    12.         //If you want to clamp the position you would place your values here.
    13.         playerPosition = Mathf.Clamp (playerPosition, -Screen.height, Screen.height);
    14.         //-------------------------------^ value--------^ minimum-------^ maximum
    15.  
    16.     }
    17.  
    18.     void FixedUpdate()
    19.     {
    20.         //This is called on FixedUpdate so that it's not dependent on frame rate.
    21.         transform.position = new Vector2 (0, playerPosition);
    22.     }
     
  3. Retruate

    Retruate

    Joined:
    Jul 5, 2014
    Posts:
    111
    Thanks for the code, Input.mousePosition doesn't give me my desired affect (as it's measured in pixel coordinates) so I'll go with my current method. I can use Mathf.Clamp though. Thanks.
     
  4. jmjd

    jmjd

    Joined:
    Nov 14, 2012
    Posts:
    48
    You're right that Input.mousePosition is in screen coordinates, so we need some way of converting those coordinates, into world coordinates for the quad.

    To do this we use our camera to convert it. Here is the call:
    Code (CSharp):
    1. Camera.main.ScreenToWorldPoint(Input.mousePosition)

    So now all we need to do is update the quad's y position with the point we get from the call above, and then clamp it so it doesn't go past where we want it to. Here's the full script, using the rigidbody2D to move it around:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PaddleMovement : MonoBehaviour
    5. {
    6.     public float maxY = 3.5f;
    7.  
    8.     private Rigidbody2D rb2D;
    9.  
    10.     void Start()
    11.     {
    12.         rb2D = GetComponent<Rigidbody2D>();
    13.     }
    14.  
    15.     void Update()
    16.     {
    17.         float newY = Camera.main.ScreenToWorldPoint(Input.mousePosition).y;
    18.  
    19.         Vector2 pos = rb2D.position;
    20.         pos.y = Mathf.Clamp(newY, -maxY, maxY);
    21.         rb2D.MovePosition(pos);
    22.     }
    23. }

    Hope this helps! Here's a little .gif I made showing what it can do!

    pong.gif
     
    Last edited: Nov 3, 2015
    Retruate and martinmr like this.
  5. Retruate

    Retruate

    Joined:
    Jul 5, 2014
    Posts:
    111
    Thank you very much for all your help. I actually saw that line of code in Monodevelop's autofill feature (it might not be called that, but it works like autofill), but I didn't know how to use it. I was going to implement it before I replied, but when I went into my project, everything was gone except for the scripts themselves! Now that I know how to use that code, there isn't much use in reconfiguring everything and re-implementing the scripts, as I never intended to publish the game itself. Again, thanks for all the information. I'll probably be able to use this code soon, as it seems like it would be something that is used a lot.