Search Unity

Rotating exactly 90 degrees - specific direction [Answered]

Discussion in 'Scripting' started by haroldh, Mar 19, 2010.

  1. haroldh

    haroldh

    Joined:
    Mar 9, 2010
    Posts:
    12
    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:

    Code (csharp):
    1.  
    2.  
    3. var playerPos: Transform;
    4.  
    5. private var rotate = false;
    6.  
    7. var rotateTime = 3;
    8.  
    9. var rotationSpeed = 30;
    10.  
    11. var rotationTime = 192;
    12.  
    13. function Update () {
    14.  
    15.     if(Input.GetKeyDown("q")){
    16.  
    17.         print("rotating");
    18.        
    19.         rotate = true;
    20.  
    21.  
    22.     }
    23.     if(rotate == true){
    24.    
    25.         Rotate();
    26.    
    27.     }
    28.  
    29. }
    30.  
    31. function Rotate(){
    32.  
    33.     transform.RotateAround (playerPos.position, Vector3.up, Time.deltaTime * rotationSpeed);
    34.        
    35.     rotationTime = rotationTime- Time.deltaTime;
    36.    
    37.     if(rotationTime==0){
    38.    
    39.         rotate = false;
    40.         rotationTime = 192;
    41.        
    42.     }
    43.    
    44.    
    45. }
    46.  
    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!
     
  2. TheChronicPhenix

    TheChronicPhenix

    Joined:
    Jan 14, 2010
    Posts:
    874
    use
    Code (csharp):
    1. function Update(){
    2. if(Input.GetKeyDown("q"){
    3. transform.Rotate(0, 90, 0);
    4. }
    5. }
    6.  
    or place the 90 wherever you want to change which axis it rotates on.
     
  3. haroldh

    haroldh

    Joined:
    Mar 9, 2010
    Posts:
    12
    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.
     
  4. haroldh

    haroldh

    Joined:
    Mar 9, 2010
    Posts:
    12
    Ok, so playing around with the Vector3.Angle, I've gotten the code to work like this:

    Code (csharp):
    1.  
    2. var triggerBPos: Transform;
    3.  
    4. var triggerA: Vector3;
    5.  
    6. var triggerB: Vector3;
    7.  
    8. var playerPos: Transform;
    9.  
    10. private var rotate = false;
    11.  
    12. private var rotationAngle:float = 0;
    13.  
    14. var rotateTime = 3;
    15.  
    16. var rotationSpeed = 30;
    17.  
    18. var rotationTime = 192;
    19.  
    20. function Update () {
    21.  
    22.     triggerA = playerPos.position;
    23.    
    24.     triggerB = triggerBPos.position;
    25.  
    26.     var targetDir = triggerB - triggerA;
    27.    
    28.     var forward = playerPos.forward;
    29.  
    30.     if(Input.GetKeyDown("q")){
    31.  
    32.         print("rotating");
    33.        
    34.         rotate = true;
    35.  
    36.     }
    37.    
    38.     if(rotate == true){
    39.    
    40.         Rotate();
    41.    
    42.     }
    43.  
    44.     rotationAngle = Vector3.Angle(targetDir, forward);
    45.  
    46.     print(rotationAngle);
    47.  
    48. }
    49.  
    50. function Rotate(){
    51.  
    52.     transform.RotateAround (playerPos.position, Vector3.up, Time.deltaTime * rotationSpeed);
    53.        
    54.     rotationTime = rotationTime- Time.deltaTime;
    55.    
    56.     if(rotationAngle>=90){
    57.    
    58.         rotate = false;
    59.         rotationTime = 192;
    60.        
    61.     }
    62.    
    63.    
    64. }
    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!
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    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:

    Code (csharp):
    1. var playerPos: Transform;
    2. var rotateTime = 3.0;
    3. var rotateDegrees = 90.0;
    4. private var rotating = false;
    5.  
    6. function Update () {
    7.    if (Input.GetKeyDown("q")) {
    8.       Rotate(transform, playerPos, Vector3.up, rotateDegrees, rotateTime);
    9.    }
    10. }
    11.  
    12. function Rotate (thisTransform : Transform, otherTransform : Transform, rotateAxis : Vector3, degrees : float, totalTime : float) {
    13.     if (rotating) return;
    14.     rotating = true;
    15.    
    16.     var startRotation = thisTransform.rotation;
    17.     var startPosition = thisTransform.position;
    18.     transform.RotateAround(otherTransform.position, rotateAxis, degrees);
    19.     var endRotation = thisTransform.rotation;
    20.     var endPosition = thisTransform.position;
    21.     thisTransform.rotation = startRotation;
    22.     thisTransform.position = startPosition;
    23.    
    24.     var rate = degrees/totalTime;
    25.     for (i = 0.0; i < degrees; i += Time.deltaTime * rate) {
    26.         yield;
    27.         thisTransform.RotateAround(otherTransform.position, rotateAxis, Time.deltaTime * rate);
    28.     }
    29.  
    30.     thisTransform.rotation = endRotation;
    31.     thisTransform.position = endPosition;
    32.     rotating = false;
    33. }
    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
     
    Yaelo likes this.
  6. haroldh

    haroldh

    Joined:
    Mar 9, 2010
    Posts:
    12
    Thank you very much, Eric! It's perfect!
     
  7. sonalikare

    sonalikare

    Joined:
    Jul 20, 2010
    Posts:
    18
    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.deltaTime*5, Space.World);
    transform.Rotate(Vector3.left, Time.deltaTime*5, 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\");


    }
    }
     
  8. Charles-Van-Norman

    Charles-Van-Norman

    Joined:
    Aug 10, 2010
    Posts:
    86
    @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.
     
  9. watercat

    watercat

    Joined:
    Dec 14, 2016
    Posts:
    13
    i have sprite for Gravity who works bat player is not Roted with Gravity if you know that
    https://answers.unity.com/questions...oted.html?childToView=1442953#comment-1442953

    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); }
     
  10. dely17

    dely17

    Joined:
    Mar 2, 2018
    Posts:
    6

    thnx your code helped me with sum
     
  11. YannigSmagghe

    YannigSmagghe

    Joined:
    Nov 14, 2018
    Posts:
    6
    Update 2020 if someone else needed :)


    Code (CSharp):
    1. public Transform target;
    2.    
    3.     public Transform target;
    4.     public float rotateTime = 3.0f;
    5.     public float rotateDegrees = 90.0f;
    6.     private bool rotating = false;
    7.  
    8.     void Update()
    9.     {
    10.         if (Input.GetKeyDown(KeyCode.RightArrow) && !rotating)
    11.         {
    12.             StartCoroutine(Rotate(transform, target, Vector3.up, -rotateDegrees, rotateTime));
    13.         }
    14.  
    15.         if (Input.GetKeyDown(KeyCode.LeftArrow) && !rotating)
    16.         {
    17.             StartCoroutine(Rotate(transform, target, Vector3.up, rotateDegrees, rotateTime));
    18.         }
    19.     }
    20.  
    21.     private IEnumerator Rotate(Transform camTransform, Transform targetTransform, Vector3 rotateAxis, float degrees, float totalTime)
    22.     {
    23.         if (rotating)
    24.             yield return null;
    25.         rotating = true;
    26.  
    27.         Quaternion startRotation = camTransform.rotation;
    28.         Vector3 startPosition = camTransform.position;
    29.         // Get end position;
    30.         transform.RotateAround(targetTransform.position, rotateAxis, degrees);
    31.         Quaternion endRotation = camTransform.rotation;
    32.         Vector3 endPosition = camTransform.position;
    33.         camTransform.rotation = startRotation;
    34.         camTransform.position = startPosition;
    35.  
    36.         float rate = degrees / totalTime;
    37.         //Start Rotate
    38.         for (float i = 0.0f; Mathf.Abs(i) < Mathf.Abs(degrees); i += Time.deltaTime * rate)
    39.         {
    40.             camTransform.RotateAround(targetTransform.position, rotateAxis, Time.deltaTime * rate);
    41.             yield return null;
    42.         }
    43.  
    44.         camTransform.rotation = endRotation;
    45.         camTransform.position = endPosition;
    46.         rotating = false;
    47.     }
    48.  
     
    Last edited: Feb 17, 2020