Search code examples
c#unity-game-enginenullreferenceexceptionbehavior-tree

Unity - C# - NullReferenceException: Object reference not set to an instance of an object


EDIT

My question is different (I think..) because the last image allows me to set a GameObject to the Communication Message and Communication Message. BUT, on play, it immediately resets to None (Text) and None (Button). I don't know why this happens or how to solve this!


I am aware this question is widely covered but still I cannot solve this. I hope someone has a solution for me.

What I have

I am working with Behavior Designer, an asset for Unity. I'm making Behavior Trees and the problem occurred when using a behavior tree reference.

First, I had my Behavior Tree like this:

Behavior Tree - Search door

It searches the front door. If it is found, it will move towards it and communicate with the human playing the game.

This worked before, but now I put this behavior tree in a Behavior Tree Reference, like this:

Behavior Tree Reference

When I double click the reference, the first image shows. BUT, where it goes wrong, is this:

Human Instructions

Problem

This is the human instructions node in the first picture. It doesn't load the communication message and communication button. When I load the corresponding button, it immediately resets on playing the scenario. This happened when I loaded this behavior in the Behavior Tree Reference, and the problem didn't occur when I played this from the original tree self.

NullReferenceException: Object reference not set to an instance of an object
HumanInstructions.CommunicationElements (Boolean activeOrNot) (at Assets/HumanInstructions.cs:54)
HumanInstructions.OnAwake () (at Assets/HumanInstructions.cs:19)
BehaviorDesigner.Runtime.BehaviorManager.EnableBehavior (BehaviorDesigner.Runtime.Behavior behavior)
BehaviorDesigner.Runtime.Behavior.EnableBehavior ()
BehaviorDesigner.Runtime.Behavior.Start ()

Any ideas what could cause this and how to solve this?

The code from HumanInstructions

using UnityEngine;
using UnityEngine.UI;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
using UnityStandardAssets.Characters.FirstPerson;

public class HumanInstructions : Action
{
    public string humanInstructionsText; // The string in inspector that shows up on-screen for the human operator to communicate with UGV.
    public string messageToConsole; // Print this message to console when the action is performed SUCCESSFUL.
    public string textOnButton; // See inspector in Behavior Designer. Is used as text on button.
    public Text CommunicationMessage;
    public Button CommunicationButton;
    bool boolClicked; // Is false; when the button is clicked, it will turn TRUE, calling the IF function, returning Taskstatus SUCCESS.


    public override void OnAwake ()
    {
        CommunicationElements (false);
    }

    public override void OnStart ()
    {
        boolClicked = false;
        CommunicationElements (false);
        CommunicationButton.onClick.AddListener (ButtonClicked);
    }

    public override TaskStatus OnUpdate ()
    {
        CommunicationMessage.text = humanInstructionsText;
        CommunicationButton.GetComponentInChildren<Text> ().text = textOnButton;
        CommunicationElements (true); // The communication elements are VISIBLE on screen.
        TriggerStatusCameraView (false);
        if (boolClicked == true) { // this IF function is active when the button is clicked. See ButtonClicked () function.
            CommunicationElements (false); // Removes the communication elements from screen.
            TriggerStatusCameraView (true);
            return TaskStatus.Success;
        } else {
            return TaskStatus.Running;
        }
    }

    // The following function is called when the CommunicationButton is clicked on screen.
    void ButtonClicked ()
    {
        boolClicked = true; // Changes the value to true, so it will trigger the IF function in OnUpdate ();
        Debug.Log (messageToConsole); // Sends this message to the console.
    }

    // The following function can be called upon and turn all UI elements (such as text, buttons or images) ACTIVE or not.
    void CommunicationElements (bool activeOrNot)
    {
        CommunicationButton.gameObject.SetActive (activeOrNot);
        CommunicationMessage.gameObject.SetActive (activeOrNot);
    }

    // The following code will DISABLE camera control if the communication screen is active for the human operator
    void TriggerStatusCameraView(bool activeOrNot)
    {
        GameObject.Find ("FPSController").GetComponent<RigidbodyFirstPersonController_custom> ().enabled = activeOrNot;
    }
}

Solution

  • The solution was simple. Thanks for looking into this.

    Text CommunicationMessage = GameObject.Find("CrazyMsg").GetComponent<Text>();
    Button CommunicationButton = GameObject.Find("MissionButton").GetComponent<Button>();