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

[2D] Rotations become tighter the further left they are

Discussion in 'Scripting' started by aljovidu, Apr 30, 2014.

  1. aljovidu

    aljovidu

    Joined:
    Aug 7, 2013
    Posts:
    7
    What I'm trying to do is instantiate multiple projectiles based on one rotation, and slightly adjust the rotations of the projectiles through iteration to create a 'cone attack' effect. However, it only works well when the target is to the right of the origin/attacking unit. The rotations of the projectiles become tighter and tighter the further left the target is, until they're all overlapping when the target is directly left of the origin. Any help or insight would be greatly appreciated.

    Code (csharp):
    1.     for (var i = 0; i <= NumberOfPulses; i++)
    2.     {
    3.         var didCenter = false;
    4.         for (var n = 1; n <= BulletsPerPulse; n++)
    5.         {
    6.             if (n == 0) continue;
    7.             _playerPos = _playerTransform.position;
    8.             _myPos = _myTransform.position;
    9.  
    10.             // rotation toward player -->
    11.             var diff = _playerPos - _myPos;
    12.             diff.Normalize();
    13.             var rotZ = Mathf.Atan2(diff.y, diff.x)*Mathf.Rad2Deg;
    14.             var newRotation = Quaternion.Euler(0f, 0f, rotZ);
    15.             var newRot1 = newRotation;
    16.             var newRot2 = newRotation;
    17.             // <--
    18.  
    19.             newRot1.z += (BulletSpreadVariance*n);
    20.             newRot2.z -= (BulletSpreadVariance*n);
    21.             bullet1 = Instantiate(Projectile, _myPos, newRot1) as GameObject;
    22.             bullet2 = Instantiate(Projectile, _myPos, newRot2) as GameObject;
    23.             if (!didCenter)
    24.             {
    25.                 bullet3 = Instantiate(Projectile, _myPos, newRotation) as GameObject;
    26.                 if (bullet3)
    27.                 {
    28.                     bullet3.rigidbody2D.AddForce(bullet3.transform.right*BulletSpeed);
    29.                     Destroy(bullet3, BulletLifetime);
    30.                     didCenter = true;
    31.                 }
    32.             }
    33.  
    34.             if (!bullet1 || !bullet2) continue;
    35.  
    36.             bullet1.transform.rotation = newRot1;
    37.             bullet2.transform.rotation = newRot2;
    38.             bullet1.rigidbody2D.AddForce(bullet1.transform.right*BulletSpeed);
    39.             bullet2.rigidbody2D.AddForce(bullet2.transform.right*BulletSpeed);
    40.  
    41.             Destroy(bullet1, BulletLifetime);
    42.             Destroy(bullet2, BulletLifetime);
    43.  
    44.         }
    45.         yield return new WaitForSeconds(TimeBetweenPulses);
    46.     }
    47. }
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    You appear to be falling for a classic newbie trap: you believe that someRotation.z is equivalent to changing the Z value in the inspector. This should really be a FAQ on this forum... it comes up a lot.

    Quaternions, despite the appearance in the Inspector, are not three numbers - those are the Euler angles of the rotation. They actually contain four 0-to-1 numbers, which bear little to no superficial relation to the Euler angle numbers. In general, if you don't have a full understanding of Quaternions, you'll never want to modify a rotation's values directly - use the many helper functions provided by the class, instead.

    For your situation, I'd probably recommend using Quaternion.AngleAxis to change the rotations of your shot.
     
  3. aljovidu

    aljovidu

    Joined:
    Aug 7, 2013
    Posts:
    7
    Thanks a ton, StarManta. I'll look into that and post back with my solution if I find one.

    And yeah... Quaternions have proven to stump me a number of times over the years with Unity. I should just buckle down and learn about them once and for all...
     
  4. aljovidu

    aljovidu

    Joined:
    Aug 7, 2013
    Posts:
    7
    As promised, my solution:

    Code (csharp):
    1. {
    2.     if (n == 0) continue;
    3.     _playerPos = _playerTransform.position;
    4.     _myPos = _myTransform.position;
    5.  
    6.     var diff = _playerPos - _myPos;
    7.  
    8.     var newRotation = Quaternion.LookRotation(diff, -Vector3.forward);
    9.     newRotation.x = 0f;
    10.     newRotation.y = 0f;
    11.  
    12.     _bullet1 = Instantiate(Projectile, _myPos, newRotation * Quaternion.AngleAxis(newRotation.z + n * BulletSpreadVariance, Vector3.forward)) as GameObject;
    13.     _bullet2 = Instantiate(Projectile, _myPos, newRotation * Quaternion.AngleAxis(newRotation.z - n * BulletSpreadVariance, Vector3.forward)) as GameObject;
    14. // ^^ these two lines handle all of the rotation by instantiating it with the desired rotation using angleaxis.
    15.  
    16.     if (!didCenter)
    17.     {
    18.         _bullet3 = Instantiate(Projectile, _myPos, newRotation) as GameObject;
    19.         if (_bullet3)
    20.         {
    21.             _bullet3.rigidbody2D.AddForce(_bullet3.transform.up * BulletSpeed);
    22.             Destroy(_bullet3, BulletLifetime);
    23.             didCenter = true;
    24.         }
    25.     }
    26.  
    27.     if (!_bullet1 || !_bullet2) continue;
    28.  
    29.     _bullet1.rigidbody2D.AddForce(_bullet1.transform.up * BulletSpeed);
    30.     _bullet2.rigidbody2D.AddForce(_bullet2.transform.up * BulletSpeed);
    31.  
    32.     Destroy(_bullet1, BulletLifetime);
    33.     Destroy(_bullet2, BulletLifetime);
    34.  
    35. }
    Thanks again!
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    Just learn the helper functions. It's 100 times easier than learning the underlying math, and about 95% as useful in the context of Unity.