Im making a 2D game which will have multiple ‘brutes’. Im getting these errors:
When I launch the game: NullReferenceException: Object reference not set to an instance of an object bruteController.Start () (at Assets/Scripts/bruteController.cs:21)
When I try hitting the brute: NullReferenceException: Object reference not set to an instance of an object bruteController.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Scripts/bruteController.cs:39)
My Scripts:
LevelManager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LevelManager : MonoBehaviour {
//Adds a defineable delay to the attack
public float playerAtAnLength;
//Says whether or not the player can attack
private bool playerCanAttack;
//Use this to reference the playerController script
public playerController thePlayer;
//Use this to reference the bruteController script
public bruteController theBrute;
public bruteDeath theBruteDeath;
//Used to store the brutes last position.
public Vector3 bruteLastPosition;
//Adds a defineable delay to the animation
public float playerAtAnDelay;
//Adds a defineable delay to the actual attack
public float playerAcAtDelay;
//Tracks the players velocity
public float playerVelocity;
//Allows you to define the amount that the attack should be moved left
public double moveLeftDist;
//Player Actual Attack Remove Time is the time that it takes for the attack collider to be removed
public float playerAcAtReTi;
//Allows me to set the object which would be spawned when the player is attacking
public GameObject playerActualAttackCollider;
//Is true if the last move was right
public bool lastMoveRight;
//Allows the conversion of the players position to a double
private double playerTransformXDouble;
//Allows you to set to players attack x location when looking left
private Vector3 playerLocationLeft;
//Allows you to define the players x position moved to the left
private float playerAttackMovedLeft;
// Use this for initialization
void Start () {
//Defines what thePlayer is in the playerController script
thePlayer = FindObjectOfType<playerController>();
theBruteDeath = FindObjectOfType<bruteDeath>();
theBrute = FindObjectOfType<bruteController>();
//Starts it out so that the player can attack
playerCanAttack = true;
}
// Update is called once per frame
void Update () {
//
//
//All needed to flip the player attack when moving left
//
//
//theBruteDeath = FindObjectOfType<bruteDeath>();
//theBrute = FindObjectOfType<bruteController>();
//Sets the playerVelocity to the live playerVelocity
playerVelocity = thePlayer.playerVelocity;
//Transfers the lastMoveRight variable to this script
lastMoveRight = thePlayer.lastMoveRight;
//Converts the position to a double
playerTransformXDouble = thePlayer.transform.position.x;
//Converts the double to a float
playerAttackMovedLeft = (float)(playerTransformXDouble - moveLeftDist);
//Sets the attack to the left of the player by a certain amount
playerLocationLeft = new Vector3(playerAttackMovedLeft, thePlayer.transform.position.y, thePlayer.transform.position.z);
}
//
//
//
//THIS CODE HAPPENS WHEN THE PLAYER ATTACKS OR ATTEMPTS TO ATTACK:
//
//
//
//Is able to be called from the playerController when the player attacks
public void playerAttack()
{
//Will run if the player can attack
if(playerCanAttack == true)
{
//Calls the playerAttackCo() to start
StartCoroutine("playerAttackCo");
}
}
//The Co-routine to add the delay into the attack, so you cant spam attack.
public IEnumerator playerAttackCo()
{
//Makes the player not able to spam the attack button
playerCanAttack = false;
//Starts both co-routines below
StartCoroutine("playerAtAnCo");
//Will run if the player is moving right
if(playerVelocity >= 0.1)
{
StartCoroutine("playerAcAtCoRight");
}
//Will run if the player is still
if(playerVelocity == 0)
{
StartCoroutine("playerAcAtCoStill");
}
//Will run if the player is moving left
if(playerVelocity <= -0.1)
{
StartCoroutine("playerAcAtCoLeft");
}
//Sets the canMove variable in the playerController to false
thePlayer.GetComponent<playerController>().canMove = false;
//Adds the actual delay for the number of seconds that playerAttackDelay is defined to.
yield return new WaitForSeconds(playerAtAnLength);
//Sets the canMove variable in the playerController to true
thePlayer.GetComponent<playerController>().canMove = true;
//When the delay is over, the player can attack again.
playerCanAttack = true;
}
//This Co-routine adds enough delay so that the actual animation is played only once
public IEnumerator playerAtAnCo()
{
//Sets the isAttacking variable in the playerController to true
thePlayer.GetComponent<playerController>().isAttacking = 1;
//Adds enough delay so that the animation is displayed
yield return new WaitForSeconds(playerAtAnDelay);
//Sets the isAttacking variable in the playerController to false
thePlayer.GetComponent<playerController>().isAttacking = 0;
}
//This Co-routine adds the actual damage part into the attack
public IEnumerator playerAcAtCoRight()
{
//Sets the delay for the actual damage to be given
yield return new WaitForSeconds(playerAcAtDelay);
//Spawns the attack radius
Instantiate(playerActualAttackCollider, thePlayer.transform.position, thePlayer.transform.rotation);
}
//Lists all of the brutes?
public List<bruteController> Brute
{
//Gets a brute
get;
//Sets the brute as a current brute.
set;
}
public IEnumerator playerAcAtCoLeft()
{
//Sets the delay for the actual damage to be given
yield return new WaitForSeconds(playerAcAtDelay);
//Still need to flip instantiate transform position
Instantiate(playerActualAttackCollider, playerLocationLeft, thePlayer.transform.rotation);
}
public IEnumerator playerAcAtCoStill()
{
//Sets the delay for the actual damage to be given
yield return new WaitForSeconds(playerAcAtDelay);
//Will run if the last move was right
if(lastMoveRight == true)
{
//Will run and place the attack radius on the right if the player is facing right
Instantiate(playerActualAttackCollider, thePlayer.transform.position, thePlayer.transform.rotation);
}
//Will run if the last move is left
if (lastMoveRight == false)
{
//Will run and place the attack radius on the left if is the player is facing left
Instantiate(playerActualAttackCollider, playerLocationLeft, thePlayer.transform.rotation);
}
}
}
bruteController:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(bruteDeath))]
public class bruteController : MonoBehaviour {
//Creates the RigidBody for the brute
private Rigidbody2D bruteRigidBody;
public LevelManager theLevelManager;
public bruteHealth theBruteHealthScript;
private bruteDeath bruteDeath;
// Use this for initialization
void Start () {
//Gets the needed component for the Rigid Body
bruteRigidBody = GetComponent<Rigidbody2D>();
//Defines theLevelManager to find the object with the script attached
theLevelManager = FindObjectOfType<LevelManager>();
//Registers you to the Level Manager
theLevelManager.Brute.Add(this);
//Defines the bruteshealth script, instead of GetComponent, you may want to try FindObjectOfType<>();
theBruteHealthScript = FindObjectOfType<bruteHealth>();
//Makes the bruteDeath register as the script
bruteDeath = GetComponent<bruteDeath>();
}
// Update is called once per frame
void Update () {
}
//Occurs whenever the goblin enters a trigger collider
void OnTriggerEnter2D(Collider2D other)
{
//Checks to see if the collider was the players attack radius
if(other.tag == "playerAttack1")
{
//Starts the code in the LevelManager if the player attacked the brute
bruteDeath.thePlayerAttack1BruteDamage();
}
}
public void Kill()
{
theLevelManager.Brute.Remove(this);
bruteDeath.Kill();
}
}
bruteDeath:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bruteDeath : MonoBehaviour
{
private bruteHealth theBrute;
public Sprite deadBrute;
private Animator myAnim;
public float timeToEnd;
public LevelManager theLevelManager;
public Sprite bruteSprite;
public Vector3 brutePosition;
public Vector3 bruteRotation;
public GameObject deadBody;
private Vector3 bruteLastPosition;
//The health of the brute
public float bruteHealthPoints;
//References the playerController script
private playerController thePlayer;
private float playerAt1Dam;
// Use this for initialization
void Start()
{
theLevelManager = FindObjectOfType<LevelManager>();
theBrute = FindObjectOfType<bruteHealth>();
myAnim = GetComponent<Animator>();
bruteSprite = GetComponent<Sprite>();
//Actually finds the object with the playerController script
thePlayer = FindObjectOfType<playerController>();
//Sets the player Attack 1 Damage in this script to the defined amount in the playerController
playerAt1Dam = thePlayer.playerAttack1Dam;
}
// Update is called once per frame
void Update() {
//Checks to see if the brute has run out of health
if (bruteHealthPoints <= 0)
{
//If the brute has no health, then they are removed from the world. Eventually, add an Instantiate with particales
bruteAnimDeath();
}
}
public void bruteActualDeath()
{
bruteLastPosition = new Vector3(theBrute.transform.position.x, theBrute.transform.position.y, theBrute.transform.position.z);
addDeadBrute();
}
public void bruteAnimDeath()
{
myAnim.SetBool("bruteIsDead", true);
}
public void bruteDeathAnimDone()
{
myAnim.SetBool("bruteDeathAnimDone", true);
bruteActualDeath();
}
public void addDeadBrute()
{
Destroy(gameObject);
Instantiate(deadBody, bruteLastPosition, theBrute.transform.rotation);
}
//Kills the brute
public void Kill()
{
}
public void thePlayerAttack1BruteDamage()
{
//Takes the player attack 1 damage amount away from the brutes health.
bruteHealthPoints = bruteHealthPoints - playerAt1Dam;
}
}
Sorry for the large amount of notes in the coding, as I said I am new to this and want to know what each line of code does in case I need to change it later on.
Whenever I launch the game it instantly spawns one brute on top of one that dies randomly. Help!