I am working on my NPC's ability to detect player within a range. But when I directly refer it in the generated action script, I get a null pointer. I have double confirmed that the player is not null. If I just use GameObject.FindWithTag("Player")
, it will work.
I wish to the action class use the function provided by detector class to get pointer to the player. I am using the unity 6 behaviour package.
My Detector
class
void Start()
{
if (player == null)
{
player = GameObject.FindWithTag("Player");
}
distance = Vector3.Distance(transform.position,player.transform.position);
}
public GameObject player; // Assign this in the Unity Editor
private float detectionRadius = 100f; // Detection radius
private float distance = 0f;
void Update()
{
if (player != null)
{
distance = Vector3.Distance(transform.position, player.transform.position);
//Debug.Log($"Distance to player: {distance}");
}
}
public Boolean ifWithinDetectDistance()
{
return distance > detectionRadius ? false : true;
}
Generated action class
[NodeDescription(name: "PlayerDetector", story: "Check if [detector] has a [target]"]
public partial class PlayerDetectorAction : Action
{
[SerializeReference] public BlackboardVariable<TargetDetector> Detector;
[SerializeReference] public BlackboardVariable<GameObject> Target;
protected override Status OnStart()
{
if (Detector.Value.ifWithinDetectDistance())
{
Target.Value = Detector.Value.player;
if (Target.Value == null)
Debug.Log($"player is null");
return Status.Success;
}
return Status.Failure;
}
}
I am working on my NPC's ability to detect player within a range. But when I directly refer it in the generated action script, I get a null pointer. I have double confirmed that the player is not null. If I just use GameObject.FindWithTag("Player")
, it will work.
I wish to the action class use the function provided by detector class to get pointer to the player. I am using the unity 6 behaviour package.
My Detector
class
void Start()
{
if (player == null)
{
player = GameObject.FindWithTag("Player");
}
distance = Vector3.Distance(transform.position,player.transform.position);
}
public GameObject player; // Assign this in the Unity Editor
private float detectionRadius = 100f; // Detection radius
private float distance = 0f;
void Update()
{
if (player != null)
{
distance = Vector3.Distance(transform.position, player.transform.position);
//Debug.Log($"Distance to player: {distance}");
}
}
public Boolean ifWithinDetectDistance()
{
return distance > detectionRadius ? false : true;
}
Generated action class
[NodeDescription(name: "PlayerDetector", story: "Check if [detector] has a [target]"]
public partial class PlayerDetectorAction : Action
{
[SerializeReference] public BlackboardVariable<TargetDetector> Detector;
[SerializeReference] public BlackboardVariable<GameObject> Target;
protected override Status OnStart()
{
if (Detector.Value.ifWithinDetectDistance())
{
Target.Value = Detector.Value.player;
if (Target.Value == null)
Debug.Log($"player is null");
return Status.Success;
}
return Status.Failure;
}
}
Share
Improve this question
edited Mar 29 at 19:45
marc_s
756k184 gold badges1.4k silver badges1.5k bronze badges
asked Mar 29 at 19:41
Hugo WongHugo Wong
31 bronze badge
1 Answer
Reset to default 3Your
PlayerDetectorAction
usesBlackboardVariable<TargetDetector> Detector;
. This means the action expects to find a reference to aTargetDetector
component stored in the Behavior Tree's Blackboard.The
NullReferenceException
occurs becauseDetector.Value
is null. This implies that the Blackboard variable linked to theDetector
field in your action node has not been correctly assigned the instance of theTargetDetector
component running on your NPC.The action script itself doesn't automatically know which
TargetDetector
instance in your scene it should be talking to. You need to explicitly tell it via the Blackboard.In the Unity Editor, select the GameObject that has the Behavior Tree component.
Inspect the Behavior Tree component. You should see a section for the Blackboard.
Ensure you have a Blackboard variable defined. You might need to add one. Let's say you call it
MyTargetDetector
. The type of this variable should beObject
or, if the system allows, specificallyTargetDetector
.Assign the reference: Find the
TargetDetector
component on your NPC GameObject (either the same GameObject running the tree or another one). Drag theTargetDetector
component from the NPC's Inspector into the value field of theMyTargetDetector
Blackboard variable.Select the
PlayerDetector
node within your Behavior Tree graph editor.In the Inspector for the
PlayerDetector
node, find theDetector
field (which corresponds to yourBlackboardVariable<TargetDetector> Detector;
).Link this field to the Blackboard variable: There should be a dropdown or selection mechanism. Choose the
MyTargetDetector
variable you created and assigned in the Blackboard. Make sure it's not set to "(None)".