I'm currently working on a boss fight for my game.
My problem is that I keep getting a NullReferenceException
error that prevents the boss (named The Smallest Stain) from moving in the Shoot State. I understand the different meanings of this error, but I don't understand its meaning when all references are set to specific game objects.
Let's start from the beginning to make the problem clearer.
This is the battle area. The player character is on the left and the boss is on the right. When in the Shoot State, I want the boss to change their position depending on where the player is right now.
To do this, I placed triggers on all the platforms and created empty children for them that act as the boss' new positions (They're visible as blue-green circles in the image).
This image shows the objects' organization in the hierarchy:
And this is how the Animator states look like for the boss (For the purposes of this question, I don't write about the Laugh state here):
I wrote the following code and added it to each Trigger gameobject:
using UnityEngine;
public class TheSmallestStain_ShootingTriggers : MonoBehaviour
{
// These are the positions for the boss.
public Transform bossPosition1;
public Transform bossPosition2;
public Transform bossPosition3;
public Transform bossPosition4;
public Transform bossPosition5;
public Transform bossPosition6;
public Transform bossPosition7;
public Transform bossPosition8;
public Transform bossPosition9;
public Transform bossPosition10;
public static bool enteredTrigger1;
public static bool enteredTrigger2;
public static bool enteredTrigger3;
public static bool enteredTrigger4;
public static bool enteredTrigger5;
public static bool enteredTrigger6;
public static bool enteredTrigger7;
public static bool enteredTrigger8;
public static bool enteredTrigger9;
public static bool enteredTrigger10;
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject == Player.Instance.gameObject)
{
if (gameObject.name == "Trigger 1")
{
enteredTrigger1 = true;
Debug.Log("Yes! It works!"); // This Debug.Log works and I see the message every time I play the game.
}
else if (gameObject.name == "Trigger 2")
{
enteredTrigger2 = true;
}
else if (gameObject.name == "Trigger 3")
{
enteredTrigger3 = true;
}
else if (gameObject.name == "Trigger 4")
{
enteredTrigger4 = true;
}
else if (gameObject.name == "Trigger 5")
{
enteredTrigger5 = true;
}
else if (gameObject.name == "Trigger 6")
{
enteredTrigger6 = true;
}
else if (gameObject.name == "Trigger 7")
{
enteredTrigger7 = true;
}
else if (gameObject.name == "Trigger 8")
{
enteredTrigger8 = true;
}
else if (gameObject.name == "Trigger 9")
{
enteredTrigger9 = true;
}
else if (gameObject.name == "Trigger 10")
{
enteredTrigger10 = true;
}
}
}
}
Then, I used those references in this script, which is attached to "The Smallest Stain Shoot" State:
using UnityEngine;
public class TheSmallestStain_Shoot : StateMachineBehaviour
{
public float timer;
public float speed;
private Transform playerPos;
TheSmallestStain theSmallestStain;
TheSmallestStain_ShootingTriggers shootingTriggers;
GameObject theBoss;
// OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
playerPos = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
theSmallestStain = animator.GetComponent<TheSmallestStain>();
shootingTriggers = animator.GetComponent<TheSmallestStain_ShootingTriggers>();
theBoss = GameObject.Find("The Smallest Stain");
timer = 5;
}
// OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
theSmallestStain.LookAtPlayer();
if (TheSmallestStain_ShootingTriggers.enteredTrigger1 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition1.position; // The error points out to this line.
}
if (TheSmallestStain_ShootingTriggers.enteredTrigger2 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition2.position;
}
if (TheSmallestStain_ShootingTriggers.enteredTrigger3 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition3.position;
}
if (TheSmallestStain_ShootingTriggers.enteredTrigger4 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition4.position;
}
if (TheSmallestStain_ShootingTriggers.enteredTrigger5 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition5.position;
}
if (TheSmallestStain_ShootingTriggers.enteredTrigger6 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition6.position;
}
if (TheSmallestStain_ShootingTriggers.enteredTrigger7 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition7.position;
}
if (TheSmallestStain_ShootingTriggers.enteredTrigger8 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition8.position;
}
if (TheSmallestStain_ShootingTriggers.enteredTrigger9 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition9.position;
}
if (TheSmallestStain_ShootingTriggers.enteredTrigger10 == true)
{
theBoss.transform.position = shootingTriggers.bossPosition10.position;
}
}
// OnStateExit is called when a transition ends and the state machine finishes evaluating this state
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
}
}
Now, we get to the error. I get it whenever the player enters the first Trigger and the boss enters the Shoot state. As you can see in the image, it points out to line 35, which is theBoss.transform.position = shootingTriggers.bossPosition1.position;
. Essentially, the line that should change the position of the boss to their new position. But the strange thing is that all those references are set to their objects (both in the script and Inspector). So, I don't know why it's not working.
I would appreciate it if you let me know in case I'm doing something wrong here. Thanks!
if
conditions inOnTriggerEnter2D
and replace them with something liketheBoss.AddTargetPosition(this.transform.position);
and then the boss can use it directly to position itself. \$\endgroup\$