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

Throwing an object with mouse

Discussion in '2D' started by jpet1991, Oct 1, 2018.

  1. jpet1991

    jpet1991

    Joined:
    Sep 10, 2018
    Posts:
    35
    Hello,

    I want to drag an object around when holding down the mouse button, and when i let go of the mouse button, i want to object to be thrown in the air in the direction the mouse was moving in.

    I already have to dragging functionality done, i just don't know how to approach the throwing aspect.

    my code so far:

    public class DragObject : MonoBehaviour {
    [SerializeField] float moveSpeed;
    [SerializeField] float offset = 0.05f;
    [SerializeField] float force = 100f;

    private bool following;
    // Use this for initialization
    void Start()
    {
    following = false;
    offset += 10;
    }

    // Update is called once per frame
    void Update()
    {
    if (Input.GetMouseButtonDown(0) && ((Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position).magnitude <= offset))
    {
    following = true;
    }
    if (Input.GetMouseButtonUp(0) && ((Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position).magnitude <= offset)) {
    following = false;

    }

    if (following)
    {
    transform.position = Vector2.Lerp(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), moveSpeed);
    }

    }


    }
     
  2. Marioooo

    Marioooo

    Joined:
    Sep 20, 2017
    Posts:
    6
    I'm a begginer in also i don't know what is the way this should be done... BUT... Maybe an approach that I would try, is to check on every frame the mouse position, get the distance between each position and make an average in order to get a movement speed... if its slow, the distance will be short, if its fast, distance will be high on each frame...

    So.. When Mouse Down, start a frame count, and check mouse position... sum mouse distance on a variable and divide it with counter...

    oooor... Simply use last frame distance and vector to get direction and speed... hope it helps, Good Luck!
     
    vakabaka likes this.
  3. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153
    as example with rigidbody2d but you have to change the script depended on your game.
    Code (CSharp):
    1. public class DragObject : MonoBehaviour
    2. {
    3.     [SerializeField] float moveSpeed;
    4.     [SerializeField] float offset = 0.05f;
    5.     [SerializeField] float force = 100f;
    6.  
    7.     Vector2 lastPosition;
    8.     [SerializeField] float saveDelay = 0.2f;
    9.     [SerializeField] float power = 5f;
    10.     bool nextSave = true;
    11.  
    12.     private bool following;
    13.     Rigidbody2D rb;
    14.     Vector2 dir;
    15.     bool canBePushed;
    16.  
    17.     // Use this for initialization
    18.     void Start()
    19.     {
    20.         following = false;
    21.         offset += 10;
    22.         lastPosition = transform.position;
    23.         rb = GetComponent<Rigidbody2D>();
    24.     }
    25.  
    26.     // Update is called once per frame
    27.     void Update()
    28.     {
    29.         if (Input.GetMouseButtonDown(0) && ((Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position).magnitude <= offset))
    30.         {
    31.             following = true;
    32.         }
    33.         if (Input.GetMouseButtonUp(0) && ((Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position).magnitude <= offset))
    34.         {
    35.             following = false;
    36.             dir = (Vector2)transform.position - lastPosition;
    37.             canBePushed = true;
    38.         }
    39.  
    40.         if (following)
    41.         {
    42.             transform.position = Vector2.Lerp(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), moveSpeed);
    43.         }
    44.  
    45.         if (nextSave)
    46.         {
    47.             StartCoroutine("SavePosition");
    48.         }
    49.     }
    50.  
    51.     void FixedUpdate ()
    52.     {
    53.         if (canBePushed)
    54.         {
    55.             canBePushed = false;
    56.             rb.velocity = dir * power;
    57.         }
    58.     }
    59.  
    60.     IEnumerator SavePosition()
    61.     {
    62.         nextSave = false;
    63.         lastPosition = transform.position;
    64.         yield return new WaitForSeconds(saveDelay);
    65.         nextSave = true;
    66.     }
    67.  
    68. }
    With one savepoint you can throw the object direct after the save was made and then it will not fly. Also it is better to use more save points. And calculate the direction between the last and one befor points.
    Code (CSharp):
    1. for (int i = 0; i < lastPositions.Length - 1; i++)
    2.         {
    3.             lastPositions[i] = lastPositions[i + 1];
    4.         }
    5.         lastPositions[lastPositions.Length - 1] = transform.position;
    6. //then dir = lastPositions [lastPositions.Length - 1] - lastPositions [lastPositions.Length - 2];
    7.  
     
    Last edited: Oct 1, 2018
    Marioooo likes this.
  4. jpet1991

    jpet1991

    Joined:
    Sep 10, 2018
    Posts:
    35
    you guys are awesome, i'll definitely go try these out!
     
  5. jpet1991

    jpet1991

    Joined:
    Sep 10, 2018
    Posts:
    35
    I've run into a problem where if I have more than one gameobject and once i click on only one, all other gameobjects will appear at the point where the mouse was clicked. I want to be able to have multiple gameobjects run onto screen and the player must drag each one off the screen. Is there anyway you can point me in the right direction in this code to solve this bug? Thank you in advanced.
     
  6. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153
    your script checks the distance from the mouse to the object. Also you can lower offset (and delete the line 21: offset += 10 but think about default camera -10, the mouse z.position will be -10 to. Then you should convert this -10 value to the same z.value as by gameobject).
    Code (CSharp):
    1. public class DragObject : MonoBehaviour
    2. {
    3.     [SerializeField] float moveSpeed;
    4.     [SerializeField] float offset = 0.05f;
    5.     [SerializeField] float force = 100f;
    6.  
    7.     Vector2 lastPosition;
    8.     [SerializeField] float saveDelay = 0.2f;
    9.     [SerializeField] float power = 5f;
    10.     bool nextSave = true;
    11.  
    12.     private bool following;
    13.     Rigidbody2D rb;
    14.     Vector2 dir;
    15.     bool canBePushed;
    16.  
    17.     // Use this for initialization
    18.     void Start()
    19.     {
    20.         following = false;
    21.         lastPosition = transform.position;
    22.         rb = GetComponent<Rigidbody2D>();
    23.     }
    24.  
    25.     // Update is called once per frame
    26.     void Update()
    27.     {
    28.         if (Input.GetMouseButtonDown(0))
    29.         {
    30.             Vector2 tmp = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    31.             if ((tmp - (Vector2)transform.position).magnitude <= offset)
    32.             {
    33.                 following = true;
    34.             }
    35.         }
    36.         if (Input.GetMouseButtonUp(0))
    37.         {
    38.             Vector2 tmp = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    39.             if ((tmp - (Vector2)transform.position).magnitude <= offset)
    40.             {
    41.                 following = false;
    42.                 dir = (Vector2)transform.position - lastPosition;
    43.                 canBePushed = true;
    44.             }
    45.         }
    46.  
    47.         if (following)
    48.         {
    49.             transform.position = Vector2.Lerp(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), moveSpeed);
    50.         }
    51.  
    52.         if (nextSave)
    53.         {
    54.             StartCoroutine("SavePosition");
    55.         }
    56.     }
    57.  
    58.     void FixedUpdate()
    59.     {
    60.         if (canBePushed)
    61.         {
    62.             canBePushed = false;
    63.             rb.velocity = dir * power;
    64.         }
    65.     }
    66.  
    67.     IEnumerator SavePosition()
    68.     {
    69.         nextSave = false;
    70.         lastPosition = transform.position;
    71.         yield return new WaitForSeconds(saveDelay);
    72.         nextSave = true;
    73.     }
    74.  
    75. }
    other way, you can try something other for objects check. As example with raycast
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DragObject : MonoBehaviour
    6. {
    7.     [SerializeField] float moveSpeed;
    8.     [SerializeField] float force = 100f;
    9.  
    10.     Vector2 lastPosition;
    11.     [SerializeField] float saveDelay = 0.2f;
    12.     [SerializeField] float power = 5f;
    13.     bool nextSave = true;
    14.  
    15.     private bool following;
    16.     Rigidbody2D rb;
    17.     Vector2 dir;
    18.     bool canBePushed;
    19.  
    20.     // Use this for initialization
    21.     void Start()
    22.     {
    23.         following = false;
    24.         lastPosition = transform.position;
    25.         rb = GetComponent<Rigidbody2D>();
    26.     }
    27.  
    28.     // Update is called once per frame
    29.     void Update()
    30.     {
    31.         if (Input.GetMouseButtonDown(0) && !following)
    32.         {
    33.             RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector3.forward);
    34.             if (hit.collider != null && hit.collider.gameObject == this.gameObject)
    35.             {
    36.                 following = true;
    37.             }
    38.         }
    39.         if (Input.GetMouseButtonUp(0))
    40.         {
    41.             following = false;
    42.             dir = (Vector2)transform.position - lastPosition;
    43.             canBePushed = true;
    44.         }
    45.  
    46.         if (following)
    47.         {
    48.             transform.position = Vector2.Lerp(transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), moveSpeed);
    49.         }
    50.  
    51.         if (nextSave)
    52.         {
    53.             StartCoroutine("SavePosition");
    54.         }
    55.     }
    56.  
    57.     void FixedUpdate ()
    58.     {
    59.         if (canBePushed)
    60.         {
    61.             canBePushed = false;
    62.             rb.velocity = dir * power;
    63.         }
    64.     }
    65.  
    66.     IEnumerator SavePosition()
    67.     {
    68.         nextSave = false;
    69.         lastPosition = transform.position;
    70.         yield return new WaitForSeconds(saveDelay);
    71.         nextSave = true;
    72.     }
    73.  
    74. }
    or you can try with OnMouseOver event and one boolean
    https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseOver.html
     
    Last edited: Oct 2, 2018
    Marioooo likes this.
  7. jpet1991

    jpet1991

    Joined:
    Sep 10, 2018
    Posts:
    35
    Vakabaka, you are awesome man. I'm pretty new to coding and this is helping me learn a lot! Thank you for the detailed explanations