Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

2D Mouse Point/Click Movement System + Quick Tutorial

Discussion in '2D' started by Ahackit, Dec 17, 2013.

  1. Ahackit

    Ahackit

    Joined:
    May 5, 2013
    Posts:
    2
    Hey guys, I have just started studying Unity and have been trying to find out as much as possible! I love the new 2D features, Well I have been trying to get a 2D Mouse Point/Click system to work. After searching online for a while I didn't find any good example or tutorial on why or how you should do it, just different code examples that helped me get to this point.

    I wanted to help explain this fully so that anyone who might read this could get a real good grasp of how this is working.

    I would also like to note I have no idea if this is the proper way to do it by any means, or if there is a more efficient way of doing it, but I at least wanted to share this really quick and simple way of doing it for any newbies out there. This code is in C# if you need help with JS let me know.

    Full Code:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class PlayerMovement : MonoBehaviour {
    6.    
    7.     public Vector3 targetPosition;
    8.    
    9.     // Update is called once per frame
    10.     void Update () {
    11.  
    12.         if(Input.GetKeyDown(KeyCode.Mouse0))
    13.            {
    14.             targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    15.         }
    16.  
    17.         transform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * 5);
    18.     }
    19. }
    20.  
    21.  

    The most important part that I found out and kept giving me the slip up was this line

    Code (csharp):
    1. targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    Input.MousePosition returns the X/Y coordinates of what I believe to be the ViewPort Coordinates(So basically where your mouse position is within your monitor).

    Your objects.Transform point system is related to the WorldPoint coordinate system which is entirely different.

    So you would click on a position on the screen and the X/Y coordinates that returned would be (457,640), my player continually moved to the top right hand of the screen. When switching to the WorldPoint system, the coordinates of when you mouse click come back as the correct x/y/z position that your player needs to move correctly towards that position.

    Code (csharp):
    1. transform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * 5);
    This is the final part, there is many different ways of actually performing this step, but this I found to be the most simple. You simply just want to use the built in .MoveTowards method. This function does actually what it looks like it moves you to the targeted position that you give it, Simply provide the correct parameters and boom bada boom, your point click movement system is working.


    This is a very short code example, but after the amount of time I spent on it I found it so stupid how little of code was actually needed, so I at least wanted to provide it to anyone who was looking or was wondering how to do it.


    If you have any questions feel free to ask and leave any feedback for me, I am still very new to all of this and I would love constructive feedback as well!

    Thanks guy.

    - Austin
     
    DLeb, nowobulae, PatMoloney and 2 others like this.
  2. softwizz

    softwizz

    Joined:
    Mar 12, 2011
    Posts:
    794
    Its nice when people actually provide the solution to a problem instead of just saying 'I got it working now'

    This little snippet of code could save others hours of searching.

    Thanks a lot for taking the time to post this.
     
  3. Ahackit

    Ahackit

    Joined:
    May 5, 2013
    Posts:
    2
    Exactly the point of the post, if I could help someone out or save some time for someone by just posting this very simple fix to a annoying problem I ran into, the post was worth it. I appreciate the gratitude.

    Cheers
     
  4. NightShroud

    NightShroud

    Joined:
    Mar 23, 2014
    Posts:
    8
    very helpful :) but im trying to use this for a 2D game and the player keeps going through the wall, and since its a topdown game i cant use vector2 i guess
    any idea how to make it move only in x and z direction?
     
  5. Batlad

    Batlad

    Joined:
    Jul 23, 2013
    Posts:
    1
    Hi, while I couldn't get your code to do what I wanted I found it a great starting point. I combined your ideas with a keyboard based movement tutorial and came up with the following code. The idea is that the player will move at a fixed speed (which can be different for both x y directions) and then stop once they reach the point you clicked. Just attach the script to the object in question and try it out.

    Also it uses the physics system so that may help with collisions and what not.

    Full Code:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Mouse_Control : MonoBehaviour {
    6.     /// <summary>
    7.     /// 1 - The speed of the ship
    8.     /// </summary>
    9.     public Vector2 speed = new Vector2(5f, 2f);
    10.  
    11.     //The position you clicked
    12.     public Vector2 targetPosition;
    13.     //That position relative to the players current position (what direction and how far did you click?)
    14.     public Vector2 relativePosition;
    15.    
    16.     // 2 - Store the movement
    17.     private Vector2 movement;
    18.    
    19.     void Update()
    20.     {
    21.         // 3 - Retrieve the mouse position
    22.         if(Input.GetKeyDown(KeyCode.Mouse0))   
    23.         {  
    24.             targetPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    25.         }
    26.  
    27.         //4 - Find the relative poistion of the target based upon the current position
    28.         // Update each frame to account for any movement
    29.         relativePosition = new Vector2(
    30.             targetPosition.x - gameObject.transform.position.x,
    31.             targetPosition.y - gameObject.transform.position.y );
    32.     }
    33.    
    34.     void FixedUpdate()
    35.     {
    36.         // 5 - If you are about to overshoot the target, reduce velocity to that distance
    37.         //      Else cap the Movement by a maximum speed per direction (x then y)
    38.         if( speed.x * Time.deltaTime >=  Mathf.Abs(relativePosition.x)) {
    39.             movement.x = relativePosition.x;   
    40.         } else{
    41.             movement.x = speed.x * Mathf.Sign(relativePosition.x);
    42.         }
    43.         if( speed.y * Time.deltaTime >=  Mathf.Abs(relativePosition.y) ) {
    44.             movement.y = relativePosition.y;
    45.         } else{
    46.             movement.y = speed.y * Mathf.Sign(relativePosition.y);
    47.         }
    48.  
    49.         // 6 - Move the game object using the physics engine
    50.         rigidbody2D.velocity = movement;
    51.  
    52.     }
    53. }
    54.  
    The tutorial in question was http://pixelnest.io/tutorials/2d-game-unity/player-and-enemies/

    Hope this is useful to someone, the if statements took me a while to nail down due to not realising I had to compensate for delta time.
     
    Last edited: Apr 3, 2014
  6. Luthy

    Luthy

    Joined:
    Mar 13, 2018
    Posts:
    1
    Thank you very much for this piece of code. It was exactly what I needed and saved me many more hours of searching and experimenting.

     
  7. LAKSHAYMAVIA

    LAKSHAYMAVIA

    Joined:
    Aug 28, 2018
    Posts:
    14
    Thank you so much Batlad. I just want to ask
    In the FixedUpdate function . What this line will do.
    if( speed.x * Time.deltaTime >= Mathf.Abs(relativePosition.x))
    Can you please explain.
    Thank you so much in advance. Hope to get a reply soon.
     
  8. Sici9

    Sici9

    Joined:
    Sep 28, 2018
    Posts:
    1
    Still five years later this post has been quite helpful, great! ;)
     
    LAKSHAYMAVIA likes this.
  9. KatieN

    KatieN

    Joined:
    Jan 26, 2019
    Posts:
    1
    I know this an old thread, but I wanted to post this for other people who might come across it (as I did) looking for an answer. Keep in mind I am new to Unity so I have no clue if this a "correct" solution. But I believe that since you are in 2d you need Vector2 not Vector3. Vector2 gives 2 dimensions (x and y.) Vector3 gives 3 dimensions (x, y, and z.) I just changed the two instances of Vector3 to Vector2 and it worked! Thanks so much! I've been searching for an answer to this for the past two days and this post is the only one that actually got my script working.
     
  10. rockysam888

    rockysam888

    Joined:
    Jul 28, 2009
    Posts:
    650
    Thank your for sharing.