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

How can I use a flag to decide if to use the mouse hold down to drag an object or single click?

Discussion in 'Scripting' started by benziavrumi, Apr 22, 2020.

  1. benziavrumi

    benziavrumi

    Joined:
    Apr 19, 2020
    Posts:
    10
    The original script :

    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using UnityEngine;
    5.  
    6. namespace UnityStandardAssets.Utility
    7. {
    8.     public class DragRigidbody : MonoBehaviour
    9.     {
    10.         public bool useMouseHoldDown = true;
    11.  
    12.         [SerializeField] private Camera mainCamera;
    13.  
    14.         const float k_Spring = 50.0f;
    15.         const float k_Damper = 5.0f;
    16.         const float k_Drag = 10.0f;
    17.         const float k_AngularDrag = 5.0f;
    18.         const float k_Distance = 0.2f;
    19.         const bool k_AttachToCenterOfMass = false;
    20.  
    21.         private SpringJoint m_SpringJoint;
    22.         private bool isDragging;
    23.  
    24.         private void Awake()
    25.         {
    26.             if (!mainCamera) mainCamera = GetComponent<Camera>();
    27.             if (!mainCamera) mainCamera = Camera.main;
    28.         }
    29.  
    30.         private void Update()
    31.         {
    32.             if (!Input.GetMouseButtonDown(0) || isDragging) return;
    33.  
    34.             // Make sure the user pressed the mouse down
    35.             if (!Input.GetMouseButtonDown(0))
    36.             {
    37.                 return;
    38.             }
    39.  
    40.             // We need to actually hit an object
    41.             RaycastHit hit = new RaycastHit();
    42.             if (
    43.                 !Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition).origin,
    44.                                  mainCamera.ScreenPointToRay(Input.mousePosition).direction, out hit, 100,
    45.                                  Physics.DefaultRaycastLayers))
    46.             {
    47.                 return;
    48.             }
    49.             // We need to hit a rigidbody that is not kinematic
    50.             if (!hit.rigidbody || hit.rigidbody.isKinematic)
    51.             {
    52.                 return;
    53.             }
    54.  
    55.             if (!m_SpringJoint)
    56.             {
    57.                 var go = new GameObject("Rigidbody dragger");
    58.                 Rigidbody body = go.AddComponent<Rigidbody>();
    59.                 m_SpringJoint = go.AddComponent<SpringJoint>();
    60.                 body.isKinematic = true;
    61.             }
    62.  
    63.             m_SpringJoint.transform.position = hit.point;
    64.             m_SpringJoint.anchor = Vector3.zero;
    65.  
    66.             m_SpringJoint.spring = k_Spring;
    67.             m_SpringJoint.damper = k_Damper;
    68.             m_SpringJoint.maxDistance = k_Distance;
    69.             m_SpringJoint.connectedBody = hit.rigidbody;
    70.  
    71.             StartCoroutine("DragObject", hit.distance);
    72.         }
    73.  
    74.  
    75.         private IEnumerator DragObject(float distance)
    76.         {
    77.             isDragging = true;
    78.  
    79.             var oldDrag = m_SpringJoint.connectedBody.drag;
    80.             var oldAngularDrag = m_SpringJoint.connectedBody.angularDrag;
    81.             m_SpringJoint.connectedBody.drag = k_Drag;
    82.             m_SpringJoint.connectedBody.angularDrag = k_AngularDrag;
    83.  
    84.             if (useMouseHoldDown == false && Input.GetMouseButtonDown(0))
    85.             {
    86.                 while (Input.GetMouseButton(0))
    87.                 {
    88.                     var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    89.                     m_SpringJoint.transform.position = ray.GetPoint(distance);
    90.                     yield return null;
    91.                 }
    92.             }
    93.             else
    94.             {
    95.                 while (!Input.GetMouseButton(0))
    96.                 {
    97.                     var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    98.                     m_SpringJoint.transform.position = ray.GetPoint(distance);
    99.                     yield return null;
    100.                 }
    101.             }
    102.             if (m_SpringJoint.connectedBody)
    103.             {
    104.                 m_SpringJoint.connectedBody.drag = oldDrag;
    105.                 m_SpringJoint.connectedBody.angularDrag = oldAngularDrag;
    106.                 m_SpringJoint.connectedBody = null;
    107.             }
    108.  
    109.             isDragging = false;
    110.         }
    111.     }
    112. }
    113.  
    I want to add/make two more options :

    1. If useMouseHoldDown is false then if you make single click on the object without holding down the mouse it will start dragging the object and another single click will drop the object.

    2. If useMouseHoldDown is true then just like now drag the object until the user stop holding down.

    3, Make that the object will start be dragging just if the user move the mouse over the object like grabbing object then use a single click to drop it.

    What I did so far and tried is this :

    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using UnityEngine;
    5.  
    6. namespace UnityStandardAssets.Utility
    7. {
    8.     public class DragRigidbody : MonoBehaviour
    9.     {
    10.         public bool useMouseHoldDown = true;
    11.  
    12.         [SerializeField] private Camera mainCamera;
    13.  
    14.         const float k_Spring = 50.0f;
    15.         const float k_Damper = 5.0f;
    16.         const float k_Drag = 10.0f;
    17.         const float k_AngularDrag = 5.0f;
    18.         const float k_Distance = 0.2f;
    19.         const bool k_AttachToCenterOfMass = false;
    20.  
    21.         private SpringJoint m_SpringJoint;
    22.         private bool isDragging;
    23.  
    24.         private void Awake()
    25.         {
    26.             if (!mainCamera) mainCamera = GetComponent<Camera>();
    27.             if (!mainCamera) mainCamera = Camera.main;
    28.         }
    29.  
    30.         private void Update()
    31.         {
    32.             /*if (!Input.GetMouseButtonDown(0) || isDragging) return;
    33.  
    34.             // Make sure the user pressed the mouse down
    35.             if (!Input.GetMouseButtonDown(0))
    36.             {
    37.                 return;
    38.             }*/
    39.  
    40.             // We need to actually hit an object
    41.             RaycastHit hit = new RaycastHit();
    42.             if (
    43.                 !Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition).origin,
    44.                                  mainCamera.ScreenPointToRay(Input.mousePosition).direction, out hit, 100,
    45.                                  Physics.DefaultRaycastLayers))
    46.             {
    47.                 return;
    48.             }
    49.             // We need to hit a rigidbody that is not kinematic
    50.             if (!hit.rigidbody || hit.rigidbody.isKinematic)
    51.             {
    52.                 return;
    53.             }
    54.  
    55.             if (!m_SpringJoint)
    56.             {
    57.                 var go = new GameObject("Rigidbody dragger");
    58.                 Rigidbody body = go.AddComponent<Rigidbody>();
    59.                 m_SpringJoint = go.AddComponent<SpringJoint>();
    60.                 body.isKinematic = true;
    61.             }
    62.  
    63.             m_SpringJoint.transform.position = hit.point;
    64.             m_SpringJoint.anchor = Vector3.zero;
    65.  
    66.             m_SpringJoint.spring = k_Spring;
    67.             m_SpringJoint.damper = k_Damper;
    68.             m_SpringJoint.maxDistance = k_Distance;
    69.             m_SpringJoint.connectedBody = hit.rigidbody;
    70.  
    71.             StartCoroutine("DragObject", hit.distance);
    72.         }
    73.  
    74.  
    75.         private IEnumerator DragObject(float distance)
    76.         {
    77.             isDragging = true;
    78.  
    79.             var oldDrag = m_SpringJoint.connectedBody.drag;
    80.             var oldAngularDrag = m_SpringJoint.connectedBody.angularDrag;
    81.             m_SpringJoint.connectedBody.drag = k_Drag;
    82.             m_SpringJoint.connectedBody.angularDrag = k_AngularDrag;
    83.  
    84.             if (useMouseHoldDown == false && Input.GetMouseButtonDown(0))
    85.             {
    86.                 //while (Input.GetMouseButton(0))
    87.                 //{
    88.                     var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    89.                     m_SpringJoint.transform.position = ray.GetPoint(distance);
    90.                     yield return null;
    91.                 //}
    92.             }
    93.             else
    94.             {
    95.                 while (!Input.GetMouseButton(0))
    96.                 {
    97.                     var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
    98.                     m_SpringJoint.transform.position = ray.GetPoint(distance);
    99.                     yield return null;
    100.                 }
    101.             }
    102.             if (m_SpringJoint.connectedBody)
    103.             {
    104.                 m_SpringJoint.connectedBody.drag = oldDrag;
    105.                 m_SpringJoint.connectedBody.angularDrag = oldAngularDrag;
    106.                 m_SpringJoint.connectedBody = null;
    107.             }
    108.  
    109.             isDragging = false;
    110.         }
    111.     }
    112. }
    113.  
    Changed I did :

    Marked the while part so it will not make while on the first condition inside the IEnumerator.
    Also marked not to use this part :

    Code (csharp):
    1.  
    2. /*if (!Input.GetMouseButtonDown(0) || isDragging) return;
    3.  
    4.             // Make sure the user pressed the mouse down
    5.             if (!Input.GetMouseButtonDown(0))
    6.             {
    7.                 return;
    8.             }*/
    9.  
    With this changes I almost made the part 3 in my list of what things I'm trying to make.
    But anyway still nothing of what I want is not working.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,971
    I'm not sure I understand all your 1,2,3 use cases, particularly how 3 fits in there.

    It might be helpful to make a UI state flow diagram, and what events map between:

    - idling
    - click
    - dragging
    - the hover-drag you mention #3

    If you put those in 4 boxes and identify the specific conditions required to transition between them, it might become apparent how to proceed.

    As for distinguishing click vs drag, you usually use a heuristic that combines time held down and distance moved and decides based on those values.
     
    benziavrumi likes this.
  3. benziavrumi

    benziavrumi

    Joined:
    Apr 19, 2020
    Posts:
    10

    What I mean is for example if I want to drag an object from one place to another place, then dragging it with the mouse hold down for a long distance is not easy for the player it might be good for short distances. but if I want to make that the user pickup an item with one click and then walking/moving with the item to a long other place and then another click drop the object there ? This is my logic. Maybe I didn't mentioned it before. The idea is to pickup objects and take them with you and to be able to drop them in other places. I didn't understand at all what the hold down mouse dragging giving you ? why to keep holding the mouse down and dragging something and not doing it with one click ? but lets say in my cases I'm removing number 3. My idea is to be able to pickup objects either with holding the mouse down or using once click to pickup and drop.