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

Question Rotate Bar Based on Touch Drag

Discussion in 'Scripting' started by siddharth3322, Aug 3, 2021.

  1. siddharth3322

    siddharth3322

    Joined:
    Nov 29, 2013
    Posts:
    1,042
    I want to rotate the bar based on my finger touch draw related to the pivot point. Following test structure implementation, I have created it for testing purposes.
    test rotate bar.png

    Currently, I can able to write this code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class TestRotateController : MonoBehaviour
    6. {
    7.  
    8.     float rotateSpeed = 10f;
    9.     Vector2 touchStartPos;
    10.     Transform touchItem;
    11.     //
    12.     [SerializeField] LayerMask touchItemsMask;
    13.  
    14.     private void Update()
    15.     {
    16.         if (Input.GetMouseButtonDown(0))
    17.         {
    18.             Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    19.             Vector2 mousePos2D = new Vector2(mousePos.x, mousePos.y);
    20.  
    21.             RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero, 0f, touchItemsMask);
    22.  
    23.             if (hit.collider != null && hit.transform.CompareTag(GameConstants.TAG_RELEASE_ANGLE_BAR))
    24.             {
    25.                 touchItem = hit.transform;
    26.                 touchStartPos = mousePos2D;
    27.             }
    28.         }
    29.         else if (Input.GetMouseButton(0))
    30.         {
    31.  
    32.             if (touchItem != null && touchItem.CompareTag(GameConstants.TAG_RELEASE_ANGLE_BAR))
    33.             {
    34.  
    35.                 Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    36.                 Vector2 mousePos2D = new Vector2(mousePos.x, mousePos.y);
    37.  
    38.                 RotateReleaseAngleBar(touchStartPos, mousePos2D);
    39.  
    40.             }
    41.         }
    42.         else if (Input.GetMouseButtonUp(0))
    43.         {
    44.             touchItem = null;
    45.         }
    46.     }
    47.  
    48.     // rotate pivot parent
    49.     public void RotateReleaseAngleBar(Vector2 touchStartPosition, Vector2 touchPosition)
    50.     {
    51.         if (touchStartPosition.x > touchPosition.x)
    52.         {
    53.             transform.parent.Rotate(Vector3.forward, rotateSpeed * Time.deltaTime);
    54.         }
    55.         else if (touchStartPosition.x < touchPosition.x)
    56.         {
    57.             transform.parent.Rotate(Vector3.forward, -rotateSpeed * Time.deltaTime);
    58.         }
    59.     }
    60. }
    Now with this code, I can't able to rotate the bar as my finger is moving. The selected direction will remain proper because I have used X value to decide this but when I stop dragging my finger then also rotation remains to continue in the same direction.

    I want to stop this, I want to rotate the bar based on finger drag amount. It is a kind of experience, I want a person is rotating the bar with his finger.
     
  2. chatrat12

    chatrat12

    Joined:
    Jan 21, 2015
    Posts:
    122
    Is this the type of thing you are looking for?
    HandleRotation.gif
    If so, here is the script I came up with:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class TestRotateController : MonoBehaviour
    4. {
    5.     [SerializeField] private Collider2D m_Handle;
    6.     private Quaternion? m_RotationOffset;
    7.  
    8.     private void Update()
    9.     {
    10.  
    11.         if (Input.GetMouseButtonDown(0))
    12.         {
    13.             Vector2 mousePos = GetMousePosition();
    14.             // Is mouse inside handle collider?
    15.             if (m_Handle.OverlapPoint(mousePos))
    16.                 // Get offset rotation between up vector and mousePos
    17.                 m_RotationOffset = Quaternion.FromToRotation(GetDirectionFromPoint(mousePos), transform.up);
    18.         }
    19.         else if (Input.GetMouseButtonUp(0))
    20.             m_RotationOffset = null;
    21.  
    22.         // If rotation offset is not null, do rotation
    23.         if (m_RotationOffset != null)
    24.         {
    25.             // Debug draw offset rotation, no needed.
    26.             Debug.DrawLine(transform.position, transform.position + Quaternion.Inverse(m_RotationOffset.Value) * transform.up, Color.cyan);
    27.             // Look at cursor
    28.             transform.rotation = Quaternion.LookRotation(Vector3.forward, GetDirectionFromPoint(GetMousePosition()));
    29.             // Apply offset rotation
    30.             transform.rotation *= m_RotationOffset.Value;
    31.         }
    32.     }
    33.  
    34.     private Vector2 GetMousePosition() => Camera.main.ScreenToWorldPoint(Input.mousePosition);
    35.     private Vector2 GetDirectionFromPoint(Vector2 point) => point - (Vector2)transform.position;
    36. }
    Instead of you raycasting, I just check if the cursor overlaps the handle collider defined in the inspector. Of course raycasting is still a valid option, especially if you want a foreground object to block the interaction.