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.
-
AuthorPosts
-
August 31, 2022 at 11:23 am #39002
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.
September 3, 2022 at 9:07 pm #39018You 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); } } }
September 4, 2022 at 10:02 am #39024Hi 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,September 4, 2022 at 7:40 pm #39025Hmmm… 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.
September 5, 2022 at 2:17 am #39033Thanks so much, this works!
September 5, 2022 at 2:46 am #39034Hi 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?
September 5, 2022 at 2:06 pm #39035Sure, 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.
-
AuthorPosts
You must be logged in to reply to this topic.