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

Question Rotate cube by 90 degrees using tween transform.DoRotate

Discussion in 'Scripting' started by moEJoe82, Feb 12, 2023.

  1. moEJoe82

    moEJoe82

    Joined:
    Jun 14, 2017
    Posts:
    10
    I am trying to rotate a cube based on mouse swipe, either up/down or left/right (but not diagonally). the following code works when swiping left or right perfectly.

    However, when i swipe up (or down) for three times in a row, the first 2 swipes it rotates in the desired direction, but when i swipe one more time, it rotates in the opposite direction!

    any help is REALLY appreciated!

    Code (CSharp):
    1. public class RotateOnSwipe : MonoBehaviour
    2. {
    3.     private Vector2 startPos;
    4.     private float swipeDistanceX;
    5.     private float swipeDistanceY;
    6.     private bool isSelected;
    7.     private Vector3 axis;
    8.     private float angle;
    9.     private bool _rotationInProgress = false;
    10.  
    11.     private void OnMouseDown()
    12.     {
    13.         startPos = Input.mousePosition;
    14.         isSelected = true;
    15.     }
    16.  
    17.     private void OnMouseUp()
    18.     {
    19.         if (isSelected && !_rotationInProgress)
    20.         {
    21.             Vector2 endPos = Input.mousePosition;
    22.             swipeDistanceX = endPos.x - startPos.x;
    23.             swipeDistanceY = endPos.y - startPos.y;
    24.  
    25.             if (Mathf.Abs(swipeDistanceX) >= Mathf.Abs(swipeDistanceY))
    26.             {
    27.                 if (swipeDistanceX > 0)
    28.                 {
    29.                     axis = Vector3.up;
    30.                     angle = -90f;
    31.                 }
    32.                 else
    33.                 {
    34.                     axis = Vector3.up;
    35.                     angle = 90f;
    36.                 }
    37.             }
    38.             else if (Mathf.Abs(swipeDistanceX) < Mathf.Abs(swipeDistanceY))
    39.             {
    40.                 if (swipeDistanceY > 0)
    41.                 {
    42.                     axis = Vector3.right;
    43.                     angle = 90f;
    44.                 }
    45.                 else
    46.                 {
    47.                     axis = Vector3.right;
    48.                     angle = -90f;
    49.                 }
    50.             }
    51.  
    52.             //transform.Rotate(axis, angle, Space.World);
    53.             transform.DORotate(transform.eulerAngles + axis * angle, 0.5f).SetEase(Ease.InOutSine).OnComplete(() => { _rotationInProgress = false; isSelected = false; });
    54.  
    55.             isSelected = false;
    56.         }
    57.     }
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,004
    Fairly certain how you're calculating your target rotation isn't quite right. You're adding euler rotations with a directional vector.

    Your target rotation would be one around the desired axis combined with your current rotation. You can get a rotation around an axis with
    Quaternion.AngleAxis
    , and then combine to quaternion rotations by multiplying them.

    So just:
    Code (CSharp):
    1. Quaternion axisRotation = Quaternion.AngleAxis(angle, axis);
    2. Quaternion targetRotation = axisRotation * transform.rotation;
    And then just use
    targetRotation
    in your
    DORotate
    call.
     
  3. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    743
    It looks like you might be using using DOTween. If so, it's worth pointing out that DORotate takes an optional third parameter "RotateMode".

    So you could do:

    Code (CSharp):
    1. transform.DORotate(axis * angle, 0.5f, RotateMode.WorldAxisAdd).SetEase(Ease.InOutSine).OnComplete(() => { _rotationInProgress = false; isSelected = false; });
    2.  
     
  4. moEJoe82

    moEJoe82

    Joined:
    Jun 14, 2017
    Posts:
    10
    That actually works! the cube can be rotated multiple times without any problem.

    However, not i am facing another issue, which is the cube sometimes shakes for no reason while it is rotating like this:

     
  5. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    743
  6. moEJoe82

    moEJoe82

    Joined:
    Jun 14, 2017
    Posts:
    10
    Thanks a MILLION! it works perfectly...

    I have the latest version of DOTween, so that did not fix the problem, but using DORotateQuaternion did the job.

    Code (CSharp):
    1. Quaternion axisRotation = Quaternion.AngleAxis(angle, axis);
    2.             Quaternion targetRotation = axisRotation * transform.rotation;
    3.             transform.DORotateQuaternion(targetRotation, 0.5f).SetEase(Ease.InOutSine).OnComplete(() => { _rotationInProgress = false; isSelected = false; });
     
  7. moEJoe82

    moEJoe82

    Joined:
    Jun 14, 2017
    Posts:
    10

    Thanks a million for pointing out my mistake, now it is working with transform.DORotateQuaternion.

    Code (CSharp):
    1. Quaternion axisRotation = Quaternion.AngleAxis(angle, axis);
    2. Quaternion targetRotation = axisRotation * transform.rotation;
    3.            
    4. transform.DORotateQuaternion(targetRotation, 0.5f).SetEase(Ease.InOutSine).OnComplete(() => { _rotationInProgress = false; isSelected = false; });
     
    flashframe likes this.