how can I smoothly rotate an object to inverse direction?
Here is what I put together when trying to solve the problem. (However my guy never turns around…)
Also, how I can I check and see when I have successfully turned around.
function TurnAround()
{
if(needInverse)
{
//Get the opposite rotation needed.
rotArd = Quaternion.Inverse(transform.rotation);
needInverse = false;
}
//Rotate back.
transform.rotation = Quaternion.Slerp(transform.rotation, rotArd, 1);
if(rotArd == transform.rotation)
{
//Finished turning around.
turnAround = false;
isPickDir = true;
needInverse = true;
}
}
Quaternion.Inverse(transform.rotation) creates a rotation to make the character return to the orientation it was created or imported - I suspect that this isn’t what you want.
If you want a function to rotate some angle lower than 180, you can use Quaternion.RotateTowards in a coroutine like this:
var speed: float = 60; // speed in degrees per second
var turning: boolean = false; // this is true while turning
function TurnAngle(angle: float){
if (!turning){ // don't start another rotation while this one is running
turning = true; // tells that this rotation is running
var degrees = Mathf.Abs(angle); // calculate degrees to rotate
var dest = Quaternion.Euler(0, angle, 0) * transform.rotation;
while (degrees > 0){
var dt = speed*Time.deltaTime;
// rotate dt degrees this frame
transform.rotation = Quaternion.RotateTowards(transform.rotation, dest, dt);
degrees -= dt; // subtract the angle rotated this frame
yield; // let Unity free till the next frame
}
turning = false; // tells that rotation finished
}
}
RotateTowards goes in the shortest direction, thus for angles < -180 or > 180 the object will rotate in the opposite direction, and for exactly 180 or -180, the object may rotate around weird axes due to a quaternion problem that I call “South Pole Madness”. If you need to rotate to 180, for instance, call TurnAngle(90) two times in another coroutine, waiting turning become false before each call - like this:
function Turn180(){
while (turning) yield;
TurnAngle(90);
while (turning) yield;
TurnAngle(90);
}
Im using this for invert Input.gyro.attitude quaternion
but I have to work with Vector3 and them invert rotate
basicly I do that:
Vector3 rotation = quaternionAngle.eulerAngles ;
rotation.x *= -1 ;
rotation.y *= -1 ;
Quaternion quaternionInverted = Quaternion.Euler( rotation ) ;
look the class:
using UnityEngine;
using System.Collections;
public class DevicePosition {
// Use this for initialization
public static void start () {
Input.gyro.enabled = true;
}
// Update is called once per frame
public static Vector3 getVector () {
Vector3 rotation = Input.gyro.attitude.eulerAngles ;
rotation.x *= -1 ;
rotation.y *= -1 ;
return rotation ;
}
public static Quaternion getQuaternion(){
return Quaternion.Euler ( DevicePosition.getVector() ) ;
}
}