Hello. I have an error that started appearing right after I referenced the animator conditions in the code. If I remove the lines of code referencing the animator, the game works fine and it Debog.Log whenever the there is an enemy in lane and whenever there isnt one, correctly; but as soon as I add the animator lines of code it doesn’t work. Should the position of the parent defenders be the same as the “attacker spawners” or should the body of the defenders be the ones the same as the “attacker spawners” .Thanks.
Errors are:
NullReferenceException: Object reference not set to an instance of an object
Shooter.Start () (at Assets/Scripts/Shooter.cs:15)
NullReferenceException: Object reference not set to an instance of an object
Shooter.Update () (at Assets/Scripts/Shooter.cs:23)
NullReferenceException: Object reference not set to an instance of an object
Shooter.Update () (at Assets/Scripts/Shooter.cs:29)
public class Shooter : MonoBehaviour
{
[SerializeField] GameObject projectilePrefab, gun; // when you make the type of the variable “GameObject”, you can drag any gameObject in there, which why it is better to make the type of the variable of the GameObject the Script/Class thats on that gameObject that we are dragging into the [serializefield] is the unity interface.
// instead of adding another line of code for “gun” ([SerializeField] GameObject gun;), we can just add a comma after the “projectilePrefab” and add the “gun” there which adds two seperate variables since they are both of the same type.
Spawner myLaneSpawner;
Animator animator;
private void Start()
{
SetLaneSpawner();
animator.GetComponent<Animator>();
}
private void Update()
{
if (IsAttackerInLane())
{
// TODO: Change animation state to shooting
animator.SetBool("isAttacking", true);
Debug.Log("Shoot");
}
else
{
// TODO: Change animation state to idle
animator.SetBool("isAttacking", false);
Debug.Log("Sit and Wait");
}
}
private void fire()
{
Instantiate(projectilePrefab, gun.transform.position, Quaternion.identity);
}
// Create an array to store each of the Attacker Spawners
private void SetLaneSpawner() // ***MMMMMM*** Gets the spawner's GameObject location in relation to the spawned defender (that we placed) location.
{
//Create a variable that holds an array of all the spawners that we have in the level.
Spawner[] spawners = FindObjectsOfType<Spawner>();
foreach (Spawner spawner in spawners)
{
// A bool that returns true if the shooter(defender that shoots) is in the same lane as the spawner GameObject (which we referenced/found using the "FindObjectsOfType<Spawner>()".
// isCloseEnough = (Each spawner's y position (getting each by using the "foreach" loop) - the y position of the gameObject that this script/class is attached to (defender that shoots) <= 0 or tinniest fraction close to 0 (using "Mathf.Epsilon" because there might be a tiny tiny fraction that is more than 0).
// Need to use "Maths.abs" to prevent us from having a negative value, which will be smaller than 0 or "Mathf.Epsilon" and return true.
bool isCloseEnough = (Mathf.Abs(spawner.transform.position.y - transform.position.y) <= Mathf.Epsilon);
if (isCloseEnough) // if equals to true
{
// then the "myLaneSpawner" (variable referencing the spawner script/class) is EQUAL to the "spawner" that we just looped through in our "foreach" (which) we found using "FindObjectsOfType<Spawner>();" in the array;
myLaneSpawner = spawner;
}
}
}
// Create a mechanism to shoot or not shoot based upon whether we have an attacker in our lane.
private bool IsAttackerInLane() // Checks if there is an attacker in our lane (by checking if the "spawner" gameobjects have any children, which is where the enemyPrefabs are placed under depending on which "spawner" gameObject instantiated them)
{
// if my lane spawner child count is less than or equal to 0
// return false
if (myLaneSpawner.transform.childCount <= 0)
{
return false;
}
else
{
return true;
}
}
}