Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Projectiles that don't project

Discussion in 'Scripting' started by GeneralShrek, Aug 13, 2019.

  1. GeneralShrek

    GeneralShrek

    Joined:
    Aug 13, 2019
    Posts:
    4
    I apologize if this is a repeat of something that came before; I looked, but couldn't find anything related to this particular issue.
    The portion of the script at issue is supposed to move a launched projectile to the intended target:
    Code (CSharp):
    1. IEnumerator OpenFire(Projectile projectile)
    2. {
    3.     while (GetTargetDistance(targetEnemy) > 0.2f)
    4.         {
    5.         var dir = targetEnemy.transform.localPosition - transform.localPosition;
    6.         var angleDir = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
    7.         projectile.transform.rotation = Quaternion.AngleAxis(angleDir, Vector3.forward);
    8.         projectile.transform.localPosition = Vector2.MoveTowards(projectile.transform.localPosition, targetEnemy.transform.localPosition, 5f * Time.deltaTime);
    9.         yield return null;
    10.     }
    11.     if (projectile != null || targetEnemy == null)
    12.     {
    13.         Destroy(projectile);
    14.     }
    15. }
    Everything works getting into the while loop, but the projectiles don't move, and the console error "NullReferenceException: Object reference not set to an instance of an object" links back to the "var dir = targetEnemy....." line. Any thoughts?
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    8,315
    targetEnemy is probably null. GetTargetDistance probably deals with targetEnemy being null gracefully, but line 5 will generate an error if targetEnemy is null. Add debugging.
     
  3. GeneralShrek

    GeneralShrek

    Joined:
    Aug 13, 2019
    Posts:
    4
    Seems like you're right, but I still can't find the error. My original post had part of the conditional commented out to expose the error; the whole script is as follows:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Tower : MonoBehaviour
    6. {
    7. [SerializeField] private float timeBetweenAttacks;
    8. [SerializeField] private float attackRadius;
    9. [SerializeField] private Projectile projectile;
    10. private Enemy targetEnemy = null;
    11. private float attackCounter;
    12. private bool isAttacking = false;
    13.  
    14. void Update()
    15. {
    16. attackCounter -= Time.deltaTime;
    17. if (targetEnemy == null)
    18. {
    19. Enemy nearestEnemy = GetNearestEnemyInRange();
    20. if (nearestEnemy != null && Vector2.Distance(transform.localPosition, nearestEnemy.transform.localPosition) <= attackRadius)
    21. {
    22. Debug.Log("Enemy in Range!");
    23. targetEnemy = nearestEnemy;
    24. }
    25. }
    26. else
    27. {
    28. if (attackCounter <= 0)
    29. {
    30. Debug.Log("Ready to Fire!");
    31. isAttacking = true;
    32. attackCounter = timeBetweenAttacks;
    33. }
    34. else
    35. {
    36. isAttacking = false;
    37. }
    38. if (Vector2.Distance(transform.localPosition, targetEnemy.transform.localPosition) > attackRadius)
    39. {
    40. targetEnemy = null;
    41. }
    42. }
    43. }
    44.  
    45. void FixedUpdate()
    46. {
    47. if (isAttacking)
    48. {
    49. Debug.Log("Aim!");
    50. Attack();
    51. }
    52. }
    53.  
    54. public void Attack()
    55. {
    56. isAttacking = false;
    57. Projectile newProjectile = Instantiate(projectile) as Projectile;
    58. newProjectile.transform.localPosition = transform.localPosition;
    59. if (targetEnemy = null)
    60. {
    61. Destroy(newProjectile);
    62. }
    63. else
    64. {
    65. Debug.Log("Firing!");
    66. StartCoroutine(OpenFire(newProjectile));
    67. }
    68. }
    69.  
    70. IEnumerator OpenFire(Projectile projectile)
    71. {
    72. while (GetTargetDistance(targetEnemy) > 0.2f && targetEnemy != null && projectile != null)
    73. {
    74. var dir = targetEnemy.transform.localPosition - transform.localPosition;
    75. var angleDir = Mathf.Atan2(dir.y, dir.x) * Mathf.Rag2Deg;
    76. Debug.Log("Target at bearing " + angleDir);
    77. Debug.Log("Distance " + dir);
    78. projectile.transform.rotation = Quaternion.AngleAxis(angleDir, Vector3.forward);
    79. projectile.transform.localPosition = Vector2.MoveTowards(projectile.transform.localPosition, targetEnemy.transform.localPosition, 5f * Time.deltaTime;
    80. yield return null;
    81. }
    82. if (projectile != null || targetEnemy == null)
    83. {
    84. Destroy(projectile)
    85. }
    86. }
    87.  
    88. private float GetTargetDistance(Enemy thisEnemy)
    89. {
    90. if (thisEnemy == null)
    91. {
    92. thisEnemy = GetNearestEnemyInRange();
    93. if (thisEnemy == null)
    94. {
    95. return 0f;
    96. }
    97. }
    98. return Mathf.Abs(Vector2.Distance(transform.localPosition, thisEnemy.transform.localPosition));
    99. }
    100.  
    101. private List<Enemy> GetEnemiesInRange()
    102. {
    103. List<Enemy> enemiesInRange = new List<Enemy>();
    104. foreach(Enemy enemy in GameManager.Instance.EnemyList)
    105. {
    106. if (Vector2.Distance(transform.localPosition, enemy.transform.localPosition) <= attackRadius
    107. {
    108. enemiesInRange.Add(enemy)
    109. }
    110. }
    111. return enemiesInRange;
    112. }
    113.  
    114. private Enemy GetNearestEnemyInRange()
    115. {
    116. Enemy nearestEnemy = null;
    117. float smallestDistance = float.PositiveInfinity;
    118. foreach(Enemy enemy in GetEnemiesInRange())
    119. {
    120. if (Vector2.Distance(transform.localPosition, enemy.transform.localPosition) < smallestDistance)
    121. {
    122. smallestDistance = Vector2.Distance(transform.localPosition, enemy.transform.localPosition);
    123. nearestEnemy = enemy;
    124. }
    125. }
    126. return nearestEnemy;
    127. }
    128. }
    With the added conditions on the while loop, it never gets triggered which lends heavy weight to targetEnemy being null, but I know it's being assigned because I get the debug message "Enemy in Range!". In fact, all the debug messages up to (and including) "Firing!" all trigger properly
     
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    8,315
    Probably line 59 above. A single "=" is for assignment, so that line makes targetEnemy null instead of checking for null.

    Code (csharp):
    1. if (targetEnemy = null)
     
  5. GeneralShrek

    GeneralShrek

    Joined:
    Aug 13, 2019
    Posts:
    4
    Found the problem! Line 59 sets to null instead of compares to null
     
  6. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    8,315
    Glad you found it :p
     
    SparrowsNest likes this.
  7. GeneralShrek

    GeneralShrek

    Joined:
    Aug 13, 2019
    Posts:
    4
    Hey buddy, just wanted to say thank you for all your help. Hopefully one day I can return the favour. Cheers!
     
unityunity