News › Forums › RAIN › General Discussion and Troubleshooting › walk waypoint network (beginner)
Tagged: waypoint network
This topic contains 22 replies, has 4 voices, and was last updated by prime 1 year ago.
-
AuthorPosts
-
January 26, 2023 at 5:53 pm #35310
@tyoc213 - I don’t think you would want to add AI-specific information to objects in the environment. Instead, I think AI can track that information individually and use it as required. That can easily be done with a small mode to the code presented in this thread. However, I’m not sure how much good a “visited” flag does in this case. You will eventually run into situations where every connected node has been visited.
February 1, 2023 at 9:11 am #35434Prime, I keep struggeling where to set the priorWaypoint. I think i need an extra step to store the correct data.
When the Ai is walking towards waypoint 1,
when it arrives, it stores the waypoint in holdingWaypoint,
then it sets its new waypoint, waypoint 2 and walks towards waypoint 2,
when it arrives at waypoint 2; priorWaypoint=holdingWaypoint (waypoint 1) and holdingWaypoint becomes waypoint 2, it sets it’s new target waypoint 3, now priorWaypoint is the waypoint it came from.It think i have the logic correct, but I’m not sure where to put it in the code.
February 2, 2023 at 9:43 am #35449Here’s an updated version of the code. Given that I’ve messed this up a couple of times, I can’t say this is totally correct yet. It should be close though. I changed what we were previously calling “lastWaypoint” to be called “currentWaypoint”. Then I used the “lastWaypoint” variable to hold the prior waypoint whenever we choose a new current.
using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using RAIN.Action; using RAIN.Core; using RAIN.Representation; using RAIN.Motion; using RAIN.Navigation; using RAIN.Navigation.Graph; using RAIN.Navigation.Waypoints; [RAINAction("Choose Next Waypoint")] public class ChooseWaypoint : RAINAction { public Expression WaypointNetwork = new Expression(); //either the name of the network or a variable containing a network public Expression MoveTargetVariable = new Expression(); //the variable you want to use for the output move target private MoveLookTarget moveTarget = new MoveLookTarget(); private int currentWaypoint = -1; private int lastWaypoint = -1; private WaypointSet lastWaypointSet = null; public override ActionResult Execute(AI ai) { //Fail if a valid move target variable was not passed in if (!MoveTargetVariable.IsValid || !MoveTargetVariable.IsVariable) return ActionResult.FAILURE; //Get the waypoint set we want to use. See the function below. //Fail if no matching waypoint set is found WaypointSet waypointSet = GetWaypointSetFromExpression(ai); if (waypointSet == null) return ActionResult.FAILURE; //If our waypoint set has changed, reset our last/current waypoints if (waypointSet != lastWaypointSet) { lastWaypoint = -1; currentWaypoint = -1; lastWaypointSet = waypointSet; } //If we don't have a current waypoint, then just grab the nearest one and use it if (currentWaypoint == -1) { currentWaypoint = waypointSet.GetClosestWaypointIndex(ai.Kinematic.Position); if (currentWaypoint < 0) return ActionResult.FAILURE; moveTarget.VectorTarget = waypointSet.Waypoints[currentWaypoint].position; moveTarget.CloseEnoughDistance = Mathf.Max(waypointSet.Waypoints[currentWaypoint].range, ai.Motor.CloseEnoughDistance); if (!ai.Motor.IsAt(moveTarget)) { ai.WorkingMemory.SetItem<MoveLookTarget>(MoveTargetVariable.VariableName, moveTarget); return ActionResult.SUCCESS; } } //Check all connections to our current waypoint. Create a list of valid connections, excluding //those that go to our lastWaypoint. Choose randomly from that list NavigationGraphNode tNode = waypointSet.Graph.GetNode(currentWaypoint); if (tNode.OutEdgeCount > 0) { List<int> tConnectedNodes = new List<int>(); for (int k = 0; k < tNode.OutEdgeCount; k++) { int tIndex = ((VectorPathNode)tNode.EdgeOut(k).ToNode).NodeIndex; if ((tIndex != lastWaypoint) && (!tConnectedNodes.Contains(tIndex))) tConnectedNodes.Add(tIndex); } lastWaypoint = currentWaypoint; if (tConnectedNodes.Count == 0) currentWaypoint = ((VectorPathNode)tNode.EdgeOut(0).ToNode).NodeIndex; else currentWaypoint = tConnectedNodes[UnityEngine.Random.Range(0, tConnectedNodes.Count)]; } //Set the moveTarget based on our choice moveTarget.VectorTarget = waypointSet.Waypoints[currentWaypoint].position; moveTarget.CloseEnoughDistance = Mathf.Max(waypointSet.Waypoints[currentWaypoint].range, ai.Motor.CloseEnoughDistance); ai.WorkingMemory.SetItem<MoveLookTarget>(MoveTargetVariable.VariableName, moveTarget); return ActionResult.SUCCESS; } private WaypointSet GetWaypointSetFromExpression(AI ai) { WaypointSet waypointSet = null; if (WaypointNetwork != null && WaypointNetwork.IsValid) { if (WaypointNetwork.IsVariable) { string varName = WaypointNetwork.VariableName; if (ai.WorkingMemory.ItemExists(varName)) { Type t = ai.WorkingMemory.GetItemType(varName); if (t == typeof(WaypointRig) || t.IsSubclassOf(typeof(WaypointRig))) { WaypointRig wgComp = ai.WorkingMemory.GetItem<WaypointRig>(varName); if (wgComp != null) waypointSet = wgComp.WaypointSet; } else if (t == typeof(WaypointSet) || t.IsSubclassOf(typeof(WaypointSet))) { waypointSet = ai.WorkingMemory.GetItem<WaypointSet>(varName); } else if (t == typeof(GameObject)) { GameObject go = ai.WorkingMemory.GetItem<GameObject>(varName); if (go != null) { WaypointRig wgComp = go.GetComponentInChildren<WaypointRig>(); if (wgComp != null) waypointSet = wgComp.WaypointSet; } } else { string setName = ai.WorkingMemory.GetItem<string>(varName); if (!string.IsNullOrEmpty(setName)) waypointSet = NavigationManager.Instance.GetWaypointSet(setName); } } else { if (!string.IsNullOrEmpty(varName)) waypointSet = NavigationManager.Instance.GetWaypointSet(varName); } } else if (WaypointNetwork.IsConstant) { waypointSet = NavigationManager.Instance.GetWaypointSet(WaypointNetwork.Evaluate<string>(0, ai.WorkingMemory)); } } return waypointSet; } }
- This reply was modified 1 year, 4 months ago by prime.
February 3, 2023 at 2:42 am #35462Prime,
This is great, I’ve got the same result that what i started with, using the Unity pathfinding. But now I got the great options of Rain, to continue building my AI.
My next step will be AI to AI affoidence, but i will figure that one out on my own, or is it better to wait for the next update. I read that you guys are working on that?Thanks for all your effort en time…
February 16, 2022 at 5:43 am #35894Prime,
When the AI arrives at a deadend it just turns around and goes to the previus waypoint.
Is there a possibility to destroy the object when it arrives at a dead end. That would be great.
I could then use the same script for spawning AI.February 16, 2022 at 6:59 am #35895Sure. You are looking for 2 conditions (you can see them both in the code):
if (tNode.OutEdgeCount > 0)
and
if (tConnectedNodes.Count == 0)
If either of those happens, it means you don’t have an unvisited node to go to. That’s where you would clean things up.
June 8, 2022 at 4:42 am #38191This works exactly like I needed. Waypoints appear to be selected randomly from all connected waypoints to the current WP. I didn’t need to exlude the prior WP so the second version of the code worked great for me. Thanks!
I do get the following yellow warnings from unity though:
Assets/AI/Actions/RainRandomWaypoint.cs(61,96): warning CS0618: `RAIN.Navigation.Waypoints.Waypoint.range’ is obsolete: `Use Range instead’
Assets/AI/Actions/RainRandomWaypoint.cs(60,79): warning CS0618: `RAIN.Navigation.Waypoints.Waypoint.position’ is obsolete: `Use LocalPosition or Position instead’
Assets/AI/Actions/RainRandomWaypoint.cs(45,104): warning CS0618: `RAIN.Navigation.Waypoints.Waypoint.range’ is obsolete: `Use Range instead’
Assets/AI/Actions/RainRandomWaypoint.cs(44,87): warning CS0618: `RAIN.Navigation.Waypoints.Waypoint.position’ is obsolete: `Use LocalPosition or Position instead’
Assets/AI/Actions/RainRandomWaypoint.cs(40,52): warning CS0618: `RAIN.Navigation.Waypoints.WaypointSet.GetClosestWaypointIndex(UnityEngine.Vector3)’ is obsolete: `Use GetClosestWaypoint instead’
- This reply was modified 1 year ago by christougher.
June 10, 2022 at 6:20 am #38203Yes, you should update your code based on the information in the warnings. RAIN has changed a bit from when the original was posted.
-
AuthorPosts
You must be logged in to reply to this topic.