Rotating exactly 90 degrees - specific direction [Answered]

Hey guys. I'm currently having trouble with a bit of code which allows an object to be rotated exactly 90 degrees in a specific direction (left right). Currently I'm using this code:

var playerPos: Transform;

private var rotate = false;

var rotateTime = 3;

var rotationSpeed = 30;

var rotationTime = 192;

function Update () {

    if(Input.GetKeyDown("q")){

        print("rotating");

        rotate = true;


    }
    if(rotate == true){

        Rotate();

    }

}

function Rotate(){

    transform.RotateAround (playerPos.position, Vector3.up, Time.deltaTime * rotationSpeed);

    rotationTime = rotationTime- Time.deltaTime;

    if(rotationTime==0){

        rotate = false;
        rotationTime = 192;

    }


}

I know that this is very inefficient and I am seeing that the rotation is always +/- 0.2 degrees and would be a problem if the object is rotated too many times.

I have looked up the forums to see how we can use Vector3.Angle but I am having trouble understanding the "to" and "from" vectors and how to get them to work. Could anyone please point me in the right direction? Thank you!

use

function Update(){
if(Input.GetKeyDown("q"){
transform.Rotate(0, 90, 0);
}
}

or place the 90 wherever you want to change which axis it rotates on.

5 Likes

Hi Astrauk,

Thanks for the quick reply. However, the rotation around an object is key as I want this object to rotate around a specific game object. Also, the rotation must be carried out over a period of time. Sorry I wasn't clear about exactly what I wanted before.

Ok, so playing around with the Vector3.Angle, I’ve gotten the code to work like this:

var triggerBPos: Transform;

var triggerA: Vector3;

var triggerB: Vector3;

var playerPos: Transform;

private var rotate = false;

private var rotationAngle:float = 0;

var rotateTime = 3;

var rotationSpeed = 30;

var rotationTime = 192;

function Update () {

	triggerA = playerPos.position;
	
	triggerB = triggerBPos.position;

	var targetDir = triggerB - triggerA;
	
	var forward = playerPos.forward;

	if(Input.GetKeyDown("q")){

		print("rotating");
		
		rotate = true;

	}
	
	if(rotate == true){
	
		Rotate();
	
	}

	rotationAngle = Vector3.Angle(targetDir, forward);

	print(rotationAngle);

}

function Rotate(){

	transform.RotateAround (playerPos.position, Vector3.up, Time.deltaTime * rotationSpeed);
		
	rotationTime = rotationTime- Time.deltaTime;
	
	if(rotationAngle>=90){
	
		rotate = false;
		rotationTime = 192;
		
	}
	
	
}

However, the update function is not fast enough to stop the rotation at 90. In fact, the first piece of code seemed to hit closer to 90 degrees on a more consistent basis. Is there any way to optimize the new piece of code so that it stops at 90 degrees every single time? If not, then I’ll revert back to the old piece of code. Thanks!

You could do the RotateAround for the entire amount at once, and store the resulting position and rotation. Then restore the rotation/position and rotate around over time. When that's done, set the rotation/position to the stored value, so it should be exact:

var playerPos: Transform;
var rotateTime = 3.0;
var rotateDegrees = 90.0;
private var rotating = false;

function Update () { 
   if (Input.GetKeyDown("q")) { 
      Rotate(transform, playerPos, Vector3.up, rotateDegrees, rotateTime);
   }
}

function Rotate (thisTransform : Transform, otherTransform : Transform, rotateAxis : Vector3, degrees : float, totalTime : float) {
    if (rotating) return;
    rotating = true;

    var startRotation = thisTransform.rotation;
    var startPosition = thisTransform.position;
    transform.RotateAround(otherTransform.position, rotateAxis, degrees);
    var endRotation = thisTransform.rotation;
    var endPosition = thisTransform.position;
    thisTransform.rotation = startRotation;
    thisTransform.position = startPosition;

    var rate = degrees/totalTime;
    for (i = 0.0; i < degrees; i += Time.deltaTime * rate) {
        yield;
        thisTransform.RotateAround(otherTransform.position, rotateAxis, Time.deltaTime * rate);
    }

    thisTransform.rotation = endRotation;
    thisTransform.position = endPosition;
    rotating = false;
}

Also I'm not sure how your code was working at all, since you have at least one variable as an integer that needs to be a float to actually work.

--Eric

1 Like

Thank you very much, Eric! It's perfect!

Hi ¨
I have crane and ROV attached to it.
I can move the crane horizontally by left and right arrow keys and vertically by up and down arrow keys.
but when I suddenly relase the keys, the ROV should get swing effect o it for few seconds due to sudden stop.
I tried with the script but it woks only for a second and rotation stops.
What loop can I used instead of this?
Please help.

var frequencyMin : float = 1;
var frequencyMax : float = 2;
var magnitude : float = 0;
var timer : float =5.0;

private var randomInterval : float;

function Start () {
randomInterval = Random.Range(frequencyMin, frequencyMax);
}

function Update() {

if (Input.GetKeyDown ("left"))
{
print("dwn");

}

/transform.Rotate(Vector3.right * Time.deltaTime5, Space.World);
transform.Rotate(Vector3.left, Time.deltaTime5, Space.World);
// … at the same time as spinning relative to the global
// Y axis at the same speed.
transform.Rotate(Vector3.up * Time.deltaTime
5, Space.World);*/

if ((Input.GetKeyUp ("left"))){
this.transform.position.y += (Mathf.Cos(Time.time * randomInterval) * magnitude);
this.transform.eulerAngles.x+= (Mathf.Cos(Time.time * randomInterval) * 0.05);
this.transform.eulerAngles.y+= (Mathf.Cos(Time.time * randomInterval) * 0.01);
this.transform.eulerAngles.z+= (Mathf.Cos(Time.time * randomInterval) * 0.03);
print("up");

}
}

@EricH5H: Thanks for the script, it works perfectly!

@sonalikare: Re: I have crane and ROV attached to it.
I can move the crane horizontally by left and right arrow keys and vertically by up and down arrow keys.
but when I suddenly relase the keys, the ROV should get swing effect o it for few seconds due to sudden stop.

I don't think you should try to do this with scripting, let the physics engine handle it. Make your ROV a rigidbody that is affected by gravity, and have it follow the crane either by a smoothfollow or rope script. Then it should keep moving on its own, but still be restrained by the rope.

Doing it by scripting means the effect will not be changeable or duplicateable to different situations easily. Letting the physics engine handle it means the effect will happen in a wide variety of cases. I would look up "rope swinging prefabs" to find something you could drop in to make it work. Hope this helps.

i have sprite for Gravity who works bat player is not Roted with Gravity if you know that
https://answers.unity.com/questions/1442949/player-gravity-haw-to-roted.html?childToView=1442953#comment-1442953

https://www.youtube.com/watch?v=qdFuPWC1cGA|list=PLMhGTQfWN-kT9urtOnP3-Kde2i9wNpvBQ

the gravyti is working bat is not rotesion
pragma strict var baritita : float;

var x : float; var y : float; var z : float;

function OnTriggerStay (other : Collider) { if (other.attachedRigidbody) other.attachedRigidbody.AddForce(Vector3(x, y, z) * baritita); }

thnx your code helped me with sum

Update 2020 if someone else needed :)

public Transform target;

    public Transform target;
    public float rotateTime = 3.0f;
    public float rotateDegrees = 90.0f;
    private bool rotating = false;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.RightArrow) && !rotating)
        {
            StartCoroutine(Rotate(transform, target, Vector3.up, -rotateDegrees, rotateTime));
        }

        if (Input.GetKeyDown(KeyCode.LeftArrow) && !rotating)
        {
            StartCoroutine(Rotate(transform, target, Vector3.up, rotateDegrees, rotateTime));
        }
    }

    private IEnumerator Rotate(Transform camTransform, Transform targetTransform, Vector3 rotateAxis, float degrees, float totalTime)
    {
        if (rotating)
            yield return null;
        rotating = true;

        Quaternion startRotation = camTransform.rotation;
        Vector3 startPosition = camTransform.position;
        // Get end position;
        transform.RotateAround(targetTransform.position, rotateAxis, degrees);
        Quaternion endRotation = camTransform.rotation;
        Vector3 endPosition = camTransform.position;
        camTransform.rotation = startRotation;
        camTransform.position = startPosition;

        float rate = degrees / totalTime;
        //Start Rotate
        for (float i = 0.0f; Mathf.Abs(i) < Mathf.Abs(degrees); i += Time.deltaTime * rate)
        {
            camTransform.RotateAround(targetTransform.position, rotateAxis, Time.deltaTime * rate);
            yield return null;
        }

        camTransform.rotation = endRotation;
        camTransform.position = endPosition;
        rotating = false;
    }
7 Likes