News Forums RAIN Sample Projects, How To, and Code Animal Wandering

This topic contains 6 replies, has 2 voices, and was last updated by  Sigil 1 month ago.

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #39002

    Thrisboss
    Participant

    Hi, I would like to know how I could make an AI (animal) wander around inside my navigation mesh? (without waypoints, I mean it would be completely random )
    Thank you.

    • This topic was modified 1 month, 1 week ago by  Thrisboss.
    #39018

    Sigil
    Keymaster

    You can grab your Navigation Mesh (using the Navigation Manager) and then pick a random node out from it… something like this would probably work (untested):

    using RAIN.Navigation;
    using RAIN.Navigation.Graph;
    using RAIN.Navigation.NavMesh;
    using System.Collections.Generic;
    using UnityEngine;
    public class CubeNavGraphRig : MonoBehaviour
    {
        public void Update()
        {
            List<RAINNavigationGraph> tGraphs = NavigationManager.Instance.GraphForPoint(gameObject.transform.position);
            if (tGraphs.Count > 0)
            {
                // Pretty much guaranteed it will be a navigation mesh
                NavMeshPathGraph tGraph = (NavMeshPathGraph)tGraphs[0];
                // Pick a random node
                int tNodeIndex = UnityEngine.Random.Range(0, tGraph.Size - 1);
                NavigationGraphNode tNode = tGraph.GetNode(tNodeIndex);
                // We'll look for a poly in particular (it could be an edge)
                while (!(tNode is NavMeshPoly))
                {
                    tNodeIndex = (tNodeIndex + 1) % tGraph.Size;
                    tNode = tGraph.GetNode(tNodeIndex);
                }
                // And a random position, this will be the center of a poly
                Vector3 tRandomPosition = tNode.Position;
                // If you wanted to, you could randomize the position within the poly as well
                NavMeshPoly tPoly = (NavMeshPoly)tNode;
                // Grab a random edge
                NavMeshEdge tEdge = tPoly.GetEdgeNode(UnityEngine.Random.Range(0, tPoly.EdgeCount - 1));
                // And adjust our position to be random between the center and that edge
                tRandomPosition = Vector3.Lerp(tRandomPosition, tEdge.Position, UnityEngine.Random.value);
            }
        }
    }
    #39024

    Thrisboss
    Participant

    Hi thx for the answer,
    Im kind of new to unity and coding so can you please tell me step by step how to apply this to my mesh and ai?
    thx very much,

    #39025

    Sigil
    Keymaster

    Hmmm… well this is all assuming you are using RAIN and the RAIN behavior trees and navigation mesh. So this isn’t particular to coding or Unity, but particular to RAIN. The pseudo code for your tree would be something like this (you would need to put this tree together on your own):

    root
       sequencer
          custom action (class: ChooseRandomNavMeshTarget, target: moveTarget)
          move (move target: moveTarget)
          timer (seconds: random(1, 5))

    Just to explain that a bit, the sequencer node will allow each of its children to run as long as they continue to return running or success. So the ChooseRandomNavMeshTarget custom action (I’ll define it below) will always return success if it can find a Navigation Mesh. The move node will return success once the AI reaches its target. The timer node will return success after 1 to 5 seconds. After all of this it will repeat, choosing a new nav mesh target, moving towards it, and then waiting 1 to 5 seconds.

    The ChooseRandomNavMeshTarget would look something like this:

    using RAIN.Action;
    using RAIN.Navigation;
    using RAIN.Navigation.Graph;
    using RAIN.Navigation.NavMesh;
    using RAIN.Representation;
    using System.Collections.Generic;
    using UnityEngine;
    [RAINAction]
    public class ChooseRandomNavMeshTarget : RAINAction
    {
        public Expression Target = new Expression();
        public override ActionResult Execute(RAIN.Core.AI ai)
        {
            // Get any graphs at our AI's position
            List<RAINNavigationGraph> tGraphs = NavigationManager.Instance.GraphForPoint(ai.Kinematic.Position);
            if (tGraphs.Count == 0)
                return ActionResult.FAILURE;
            // Pretty much guaranteed it will be a navigation mesh
            NavMeshPathGraph tGraph = (NavMeshPathGraph)tGraphs[0];
            // Pick a random node
            int tNodeIndex = UnityEngine.Random.Range(0, tGraph.Size - 1);
            NavigationGraphNode tNode = tGraph.GetNode(tNodeIndex);
            // We'll look for a poly in particular (it could be an NavMeshEdge and not a poly)
            while (!(tNode is NavMeshPoly))
            {
                tNodeIndex = (tNodeIndex + 1) % tGraph.Size;
                tNode = tGraph.GetNode(tNodeIndex);
            }
            // You can randomize the position within the poly as well
            NavMeshPoly tPoly = (NavMeshPoly)tNode;
            // Grab a random edge
            NavMeshEdge tEdge = tPoly.GetEdgeNode(UnityEngine.Random.Range(0, tPoly.EdgeCount - 1));
            // And adjust our position to be random between the center and that edge
            Vector3 tRandomPosition = Vector3.Lerp(tNode.Position, tEdge.Position, UnityEngine.Random.value);
            // If the user set a Target variable, use it
            if (Target.IsVariable)
                ai.WorkingMemory.SetItem<Vector3>(Target.VariableName, tRandomPosition);
            // Otherwise juse use some default
            else
                ai.WorkingMemory.SetItem<Vector3>("randomNavMeshTarget", tRandomPosition);
            return ActionResult.SUCCESS;
        }
    }

    See if you can’t get that going in your scene and then we can build upon it.

    #39033

    Thrisboss
    Participant

    Thanks so much, this works!

    #39034

    Thrisboss
    Participant

    Hi again, is there a way to make the ai run away from an entity if it detects it visually and, or make it go to the entity to attack it?

    #39035

    Sigil
    Keymaster

    Sure, check out the Starter Kit (on our tutorial page) for some of the details on setting sensors up and the behavior tree. It also has examples of chasing and running away.

    I can help you work out implementing them in your behavior tree at that point, but it’d be good if you check out some previous setups and experiment a little.

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

You must be logged in to reply to this topic.