Bill
Bill

Reputation: 37

How to rotate Unity Quaternion and preserve original axis?

I'm working on a simple puzzle-style Unity game for iOS. The game presents the user a "rubiks cube" object (one large cube comprised of smaller cubes).

I want users to be able to swipe left/right/up/down on the cube to rotate as expected.

My code works, but after the user performs a 2nd rotation, the cube does not rotate according to the user's expected direction. After the first rotation, the x/y/z axis have rotated along with the device.

If I only use the left/right swipe code, it works as expected. When I add up/down swiping, it breaks. Which makes sense, since the axis doesn't rotate when I stick to two variables.

Here is my code:

if (Input.GetMouseButtonUp(0))
    {

        //swipe upwards
        if (currentSwipe.y > 0 && currentSwipe.x > -1f && currentSwipe.x < 1f)
        {
            GameObject.FindGameObjectWithTag("Sfx").GetComponent<SoundManager>().PlaySwipe();

            gameObject.transform.DORotateQuaternion(Quaternion.Euler(0f, 0f, 90f), 0.5f).SetRelative(true).OnComplete(SetSwiping);
        }
        //swipe down
        if (currentSwipe.y < 0 && currentSwipe.x > -1f && currentSwipe.x < 1f)
        {
            GameObject.FindGameObjectWithTag("Sfx").GetComponent<SoundManager>().PlaySwipe();

            gameObject.transform.DORotateQuaternion(Quaternion.Euler(0f, 0f, -90f), 0.5f).SetRelative(true).OnComplete(SetSwiping);
        }
        //swipe left
        if (currentSwipe.x < 0 && currentSwipe.y > -1f && currentSwipe.y < 1f)
        {
            GameObject.FindGameObjectWithTag("Sfx").GetComponent<SoundManager>().PlaySwipe();

            gameObject.transform.DORotateQuaternion(Quaternion.Euler(0f, -90f, 0f), 0.5f).SetRelative(true).OnComplete(SetSwiping);
        }
        //swipe right
        if (currentSwipe.x > 0 && currentSwipe.y > -1f && currentSwipe.y < 1f)
        {
            GameObject.FindGameObjectWithTag("Sfx").GetComponent<SoundManager>().PlaySwipe();

            gameObject.transform.DORotateQuaternion(Quaternion.Euler(0f, 90f, 0f), 0.5f).SetRelative(true).OnComplete(SetSwiping);

        }
    }

Any help is appreciated! I'm relatively new to Unity so still learning.

Upvotes: 0

Views: 314

Answers (1)

pixlhero
pixlhero

Reputation: 418

I think it is easier (at least for me) to rethink the setup like this:

private Quaternion _targetRotation; // this will jump to the rotation in discrete steps (i.e. not gradually)

Start(){
    _targetRotation = cube.transform.localRotation;
    ....
}
...
    var appliedRotation = Quaterion.identity;

    //swipe upwards
    if (currentSwipe.y > 0 && currentSwipe.x > -1f && currentSwipe.x < 1f){
        appliedRotation = Quaternion.AngleAxis(90f, Vector3.right);
    }
    ... // other swipe cases

    _targetRotation = appliedRotation * _targetRotation; // order is important afaik
    
    ...
    gameObject.transform.DOLocalRotateQuaternion(_targetRotation);

let me know if this works.

Upvotes: 1

Related Questions