News Forums RAIN General Discussion and Troubleshooting Behavior Tree Re-use

This topic contains 1 reply, has 2 voices, and was last updated by  Sigil 4 months, 1 week ago.

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #39013

    dmmiller
    Participant

    I’m trying to extend the simple patrol tutorial that was made by CodersExpo on Youtube.

    Is there a way to build a single Behavior Tree for “OneWayMovement” that I can apply to multiple AI agents with different PatrolRoutes? Whenever I try to do that in the BT Editor for a second AI agent, it changes the value of the patrol route for the BT on the first AI agent. It seems as though if I have 50 agents that need to move on 50 different routes, I may have to build 50 different BT’s, and that is a lot of repetitive work!

    I’m accustomed to using scripts in Unity that I can reuse by writing them once, including public variables, dragging them onto a GameObject in the inspector (for example, it would include a public “route” variable), and then assigning the correct route to the associated Agent’s public variable in the inspector… I only have to write the script once, and then can re-use it an infinite number of times.

    Is there a way to do this with Rain’s BT’s?

    Thanks for your help!

    #39022

    Sigil
    Keymaster

    We use variables in the behavior tree to define things that will change from AI to AI. I think the video is a bit dated, but for quick references, we often just use the names of the routes (in quotes) to link them in trees (for simple AI).

    Something along the lines of this:

    waypoint patrol (waypoint route: "Waypoint Route", move target variable: waypointTarget)
        move (move target: waypointTarget)

    But in your 50 AI case, with 50 different routes you’d have a lot of trees. Instead you could use a variable, defined in each AI’s memory, to tell it what route to go to:

    waypoint patrol (waypoint route: myPersonalRoute, move target variable: waypointTarget)
        move (move target: waypointTarget)

    You’d go to the memory tab on the AI, add a GameObject variable named myPersonalRoute, and drag the Waypoint Route of choice onto it. That’s one way at least. Another, even more automated way, would be to make a Custom Action for your AI that chooses the closest waypoint route. Something like this might work:

    using RAIN.Action;
    using RAIN.Navigation.Waypoints;
    using UnityEngine;
    [RAINAction]
    public class GetClosestWaypointRoute : RAINAction
    {
        public override ActionResult Execute(RAIN.Core.AI ai)
        {
            // This could get slow in large scenes, might need to 
            // store this ahead of time in some component
            WaypointRig[] tRigs = GameObject.FindObjectsOfType<WaypointRig>();
            WaypointRig tClosestRig = null;
            float tClosestRigDistance = float.MaxValue;
            // This could also get slow over large networks and large scenes,
            // some speed ups are coming in the next version of RAIN
            for (int i = 0; i < tRigs.Length; i++)
            {
                // We only patrol routes, as networks are for path preference
                if (tRigs[i].WaypointSet.SetType != WaypointSet.WaypointSetType.Route)
                    continue;
                // Closest waypoint
                Waypoint tClosestWaypoint = tRigs[i].WaypointSet.GetClosestWaypoint(ai.Kinematic.Position);
                // And make sure its the closest out of all of them
                float tDistance = (tClosestWaypoint.Position - ai.Kinematic.Position).sqrMagnitude;
                if (tDistance < tClosestRigDistance)
                {
                    tClosestRig = tRigs[i];
                    tClosestRigDistance = tDistance;
                }
            }
            // If we found a set we want to use, take it
            if (tClosestRig != null)
            {
                ai.WorkingMemory.SetItem<WaypointRig>("myPersonalRoute", tClosestRig);
                return ActionResult.SUCCESS;
            }
            // Didn't find a route
            return ActionResult.FAILURE;
        }
    }

    You could change the parameters of this as well, it could be the furthest WaypointRig, or a WaypointRig with a component on it, or a WaypointRig with a certain name. Lots of options.

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.