Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Having trouble with simple 2D missile homing script

Discussion in 'Scripting' started by samloeschen, Jun 25, 2014.

  1. samloeschen

    samloeschen

    Joined:
    Mar 22, 2010
    Posts:
    268
    I think my brain isn't working this morning, something in my math is wrong. The missile either doesn't rotate at all, or quickly oscillates between two angles.

    Here is my script:


    Code (JavaScript):
    1. function GetNewRotationAngle(){
    2.  
    3.     var targetAngle : float = Angle2D(Vector2(transform.position.x, transform.position.y), Vector2(target.x, target.y));
    4.      
    5.     var angleDiff : float = transform.eulerAngles.x - targetAngle;
    6.  
    7.      
    8.     if(angleDiff >= 180f){
    9.  
    10.         angleDiff -= 360f;
    11.  
    12.     }else{
    13.         if(angleDiff <= -180f){
    14.      
    15.             angleDiff += 360f;
    16.         }
    17.     }
    18.  
    19.     var turnSpeed : float = rotationDegreesPerSecond*Time.deltaTime;
    20.     var result : float;
    21.  
    22.  
    23.     if(turnSpeed<Mathf.Abs(angleDiff)){
    24.      
    25.         result = transform.eulerAngles.x + (turnSpeed * angleDiff);
    26.  
    27.     }else{
    28.         result = targetAngle;
    29.     }  
    30.  
    31.     angleDebug = angleDiff;
    32.      
    33.     return result;
    34. }
    35.  
    36. function Angle2D(current : Vector2, target : Vector2){
    37.  
    38.      return Mathf.Atan2(target.y-current.y, target.x-current.x) * Mathf.Rad2Deg;
    39. }
    40.    
    Note that I'm doing this in the 3D engine. Thanks for the help guys

    EDIT:

    thanks to bigmisterb for the solution. here is the code i ended up with that worked for me. note that i'm doing this on rigidbodies


    rotation:
    Code (JavaScript):
    1. function GetNewRotationAngle(){
    2.    
    3.     var targetDir : Vector3 = target - rigidbody.position;
    4.     targetDir.z = 0f;
    5.     var newRotation = Quaternion.LookRotation(targetDir, Vector3.forward);
    6.     var deltaRotation : Quaternion = Quaternion.RotateTowards(rigidbody.rotation, newRotation, rotationDegreesPerSecond*Time.deltaTime);
    7.    
    8.     rigidbody.MoveRotation(deltaRotation);
    9. }

    movement: (in order to get it to work on one axis, i had to clamp the z position of the rigidbody)

    Code (JavaScript):
    1.  
    2. function UpdateMovement(){
    3.     var movement : Vector3 = rigidbody.position + transform.forward * (moveSpeed * Time.deltaTime);
    4.     movement.z = 0f;
    5.     rigidbody.MovePosition(movement);
    6. }
    7.    
     
    Last edited: Jun 25, 2014
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    I almost never use angles. Quaternions are very easy to manipulate without all the extra thought.

    Code (csharp):
    1.  
    2. function DoRotation(){
    3.     var rotationDegreesPerSecond = 10;
    4.     Quaternion rotation = transform.rotation;
    5.     transform.LookAt(target);
    6.     // if you have problems with the up direction....
    7.     // transform.LookAt(target, Vector3.back);
    8.    
    9.     transform.rotation = Quaternion.RotateTowards(rotation, transform.rotation, rotationDegreesPerSecond * Time.deltaTime);
    10. }
    11.  
     
  3. samloeschen

    samloeschen

    Joined:
    Mar 22, 2010
    Posts:
    268
    I'll give this a shot. I don't understand quaternions on a mathematical level, which is why I've tried to shy away from them in the past

    quick edit: won't transform.look at make it rotate instantly instead of over time?
     
  4. samloeschen

    samloeschen

    Joined:
    Mar 22, 2010
    Posts:
    268
    Works great! one problem though is that I need to have them rotate on only one axis. how can i do that with quaternions?
     
  5. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    using an up direction will be the key to doing it on one axis.

    So if you are using 2d, then forward and backward (z) should be correct, if it is not simply replace it with transform.up.

    Code (csharp):
    1.  
    2. transform.LookAt(target, transform.up);
    3.  
    ok. Transform.LookAt makes it look instantly at the object, yes, however, keeping the other rotation back means that you can use Quaternion.RotateTowards with the original rotation. So RotateTowards will do all the actual math work, and you don't have to.