# Spin a RectTransform and have inertia by drag input?

Think of a wheel of fortune.

I need:

• Make the wheel “look at” to the drag position, like if the player was pulling the wheel (achieved)
• Calculate, somehow, the values to know the direction (clockwise, counterclockwise) and drag strength that the inertia will use
• At drag release begin inertia towards that direction with decreasing velocity over time

First point:

``````public void OnDrag (PointerEventData _pointerData)
{
Vector2 _pointerDir = _pointerData.position - base.transform.position;
float _rotationAngle = Mathf.Atan2 (_pointerDir.y, _pointerDir.x) * Mathf.Rad2Deg + -90;
base.transform.rotation = Quaternion.Euler (0, 0, _rotationAngle);
}
``````

I’m sure i can deal with the third point aswell, the problem are the calculations behind the second point.

Rigidbodies give the “angular velocity” which sounds like what i need, yet, how to achieve this with a rotation and without Rigidbody?

Keep track of the positions of the wheel as the player is dragging it. For simplicity’s sake, let’s just say we keep one frame of history. So we know the position of the wheel this frame, and we know the position last frame. We also know how much time has passed since last frame from Time.deltaTime. Calculate the angle difference of the rotation of the wheel from last frame to this frame, and divide that by the time since the last frame, and you have an angularVelocity in degrees per second.

So when you detect the user has released the wheel, you can calculate the angular velocity as per above, and start rotating by that speed. Try to get that working, then you can work on the friction part that will eventually slow the wheel down.

1 Like

That’s the interesting part PraetorBlue:

``````private float angularVelocity;
private Quaternion lastFrameRotation;

public void OnPointerDown (PointerEventData _pointerData)
{
lastFrameRotation = base.transform.rotation;
}

public void OnDrag (PointerEventData _pointerData)
{
// Look at input position.
Vector2 _pointerDir = _pointerData.position - base.transform.position;
float _rotationAngle = Mathf.Atan2 (_pointerDir.y, _pointerDir.x) * Mathf.Rad2Deg + -90;
base.transform.rotation = Quaternion.Euler (0, 0, _rotationAngle);

// Calculate angular velocity.
float _angleDifference = Quaternion.Angle (base.transform.rotation, lastFrameRotation);
angularVelocity = _angleDifference / Time.deltaTime;
lastFrameRotation = base.transform.rotation;
}

public void OnPointerUp (PointerEventData _pointerData)
{
Debug.Log (angularVelocity);
}
``````

I’m assuming that is what you meant?

Now applying angularVelocity to a Transfom.Rotate function and gradually reducing the velocity is not giving the results i expected:

``````    IEnumerator Inertia ()
{
// If angularVelocity is strong.
if (angularVelocity > 500f)
{
inerting = true;
while (inerting && angularVelocity > 0)
{
base.transform.Rotate (Vector3.forward, angularVelocity);
angularVelocity *= (1 - Time.deltaTime);
yield return null;
}
}
}
``````

The wheel friction phase is changing constantly it’s direction even if a specify Vector3.forward as the axis of the Rotate function?

Seems i need to convert the angular velocity to a usable value for the Rotate function. But i can’t find how to.