Behavior Graph "Set Random Target" node

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 documentation on 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?

Hi @mgrawr ,

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 :slight_smile:

p

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 :thinking:

I hope this helps!

1 Like

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;
        }
    }
}
1 Like

Thank you so much!! Will try it in the next days :star_struck: