I’m working on a game and decided to switch to the last Unity version to use Behavior Graph.
I’m currenlty stuck on the following task: my NPC character is supposed to roam around the scene and chose a random object to interact with from a list of object tagged with “NotSolvedTarget”. Once the user solves the riddle, the object’s tag changes to “SolvedTarget” and the NPC choses the next one.
Reading the official documentationon this page I thought I had found the perfect node for my task, which would be “Set Random Target [Target] From Tag [Tag]”, but it doesn’t seem to actually exist in the Behavior Graph interface.
I’m now trying to implement this functionality as a New Action, but the more time I spend wrapping my head around the scripting, the more I wish that node actually existed. Does anyone have any ideas or suggestions to help solve this?
The SetRandomTargetAction action is inside the sample. You can install it it from the package manager. See screenshot. Note it’ll probably say Import instead of update for you
We didn’t include it in the package because we figured finding objects by tag is generally not very good for performance so we didn’t want to encourage it, but we should probably move it there anyway
P.S. here’s the code for the action. Note, if you duplicate it and then import the sample, make sure to edit the GUID
using System;
using Unity.Properties;
using UnityEngine;
namespace Unity.Behavior.Example
{
[Serializable, GeneratePropertyBag]
[NodeDescription(
name: "Set Random Target",
description: "Assigns a target to a random object matching a given tag.",
story: "Set Random Target [Target] From Tag [TagValue]",
id: "4daff47ae1c14ec780056d158e5e0953")]
public partial class SetRandomTargetAction : Action
{
[SerializeReference] public BlackboardVariable<GameObject> Target;
[SerializeReference] public BlackboardVariable<string> TagValue;
protected override Status OnUpdate()
{
GameObject[] tagged = GameObject.FindGameObjectsWithTag(TagValue);
if (tagged == null || tagged.Length == 0)
{
return Status.Failure;
}
int randomNumber = UnityEngine.Random.Range(0, tagged.Length);
Target.Value = tagged[randomNumber];
return Status.Success;
}
}
}