News Forums RAIN General Discussion and Troubleshooting Using Unity's Built In Pathfinding System With RAIN

This topic contains 25 replies, has 5 voices, and was last updated by  Sigil 1 year ago.

Viewing 15 posts - 1 through 15 (of 26 total)
  • Author
    Posts
  • #38628

    ILoFoSho
    Participant

    Alright, I’ll keep the explanation brief, because I think the title kind of speaks for itself. Basically, I want to just be able to use Unity’s pathfinding system instead of the one that comes with it. Everything else about RAIN is perfect. I’d love to keep the sensors and the motors and whatnot, but just when it comes to finding what path you’re going to take, I want it to use Unity’s built in navigation system.
    I want to do this because I have navigation obstacles that are included in my game. They seem to carve holes in the Unity navmesh just fine, but they don’t carve holes into the RAIN navmesh. So I figure if I can just use Unity’s navmesh for the pathfinding, I won’t have a problem. How do I go about doing this?
    Or if anybody has a different solution to my problem (being able to use navigation obstacles with RAIN’s pathfinding) that would also be great!
    And a huge thanks in advance for any help that’s offered!

    #38635

    Sigil
    Keymaster

    Ok, well I’ve been meaning to attempt this for awhile anyways… so here is a first pass at a motor that uses the Unity Navigation Mesh. It appears to work for the most part, but I expect I’ll need to make additional passes at it.

    So put this in a script in your project (with RAIN). Once it compiles you can select this on your AI under the Motor tab, instead of BasicMotor. If you don’t already have a NavMeshAgent on your AI Body this will add one when you start playing. While using this, the BasicNavigator (or really any Navigator) won’t be necessary, and won’t do anything as it goes.

    Give it a shot, and let me know what happens. Oh, and after working on this a bit I expect that I’m going to overhaul the BasicMotor and RAINmotor for the next version, so a lot of this may get deprecated, but it should still work. Worst case we come back around and fix any problems. Might even make this a permanent part of RAIN.

    // Newer version later in thread
    • This reply was modified 1 year, 2 months ago by  Sigil. Reason: removed older code
    #38637

    Martin Cmar
    Participant

    I gave it a try with simple BT that just patrol a route and the navigation seems to work properly (avoiding obstacles) but AI is still following the third waypoint (out of four) only. any ideas how to work around this? thank you

    #38638

    Sigil
    Keymaster

    Do you get the same results with a Basic Motor or is specific to this one? Anything special about the AI other than the motor? Anything special about that particular waypoint?

    I can’t seem to get that particular behavior, but perhaps a screenshot with the waypoint network and the navigation mesh shown might help me figure it out.

    #38640

    ILoFoSho
    Participant

    You… are amazing!!!!!!!!!!!!!!! You’re the absolute best! This totally worked.

    I do have a couple questions though… My AI makes use of a custom Action called ChooseWanderPosition (I believe I found it in some example assets I downloaded from RAIN’s website, but I can’t remember and I can’t seem to find them again). Here’s what the script looks like:

    using UnityEngine;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using RAIN.Action;
    using RAIN.Core;
    using RAIN.Representation;
    using RAIN.Navigation;
    [RAINAction("Choose Wander Position")]
    public class ChooseWanderPosition : RAINAction
    {
    	/// <summary>
    	/// Public Expressions are editable in the Behavior Editor
    	/// WanderDistance is the max range to use when picking a wander target
    	/// </summary>
    	public Expression WanderDistance = new Expression();
    	/// <summary>
    	/// Public Expressions are editable in the Behavior Editor
    	/// StayOnGraph is a boolean (true/false) that indicates whether the wander target must be on the nav graph
    	/// </summary>
    	public Expression StayOnGraph = new Expression();
    	/// <summary>
    	/// Public Expressions are editable in the Behavior Editor
    	/// WanderTargetVariable is the name of the variable that the result will be assigned to
    	/// *Don't use quotes when typing in the variable name
    	/// </summary>
    	public Expression WanderTargetVariable = new Expression();
    	/// <summary>
    	/// The default wander distance to use when the WanderDistance is invalid
    	/// </summary>
    	private float _defaultWanderDistance = 10f;
    	public override ActionResult Execute(RAIN.Core.AI ai)
    	{
    		if (!WanderTargetVariable.IsVariable)
    			throw new Exception("The Choose Wander Position node requires a valid Wander Target Variable");
    		float tWanderDistance = 0f;
    		if (WanderDistance.IsValid)
    			tWanderDistance = WanderDistance.Evaluate<float>(ai.DeltaTime, ai.WorkingMemory);
    		if (tWanderDistance <= 0f)
    			tWanderDistance = _defaultWanderDistance;
    		Vector3 tDirection = new Vector3(UnityEngine.Random.Range(-1f, 1f), 0f, UnityEngine.Random.Range(-1f, 1f));
    		tDirection *= tWanderDistance;
    		Vector3 tDestination = ai.Kinematic.Position + tDirection;
    		if (StayOnGraph.IsValid && (StayOnGraph.Evaluate<bool>(ai.DeltaTime, ai.WorkingMemory)))
    		{
    			if (NavigationManager.Instance.GraphForPoint(tDestination, ai.Motor.MaxHeightOffset, NavigationManager.GraphType.Navmesh, ((BasicNavigator)ai.Navigator).GraphTags).Count == 0)
    				return ActionResult.FAILURE;
    		}
    		ai.WorkingMemory.SetItem<Vector3>(WanderTargetVariable.VariableName, tDestination);
    		return ActionResult.SUCCESS;
    	}
    }

    The problem is that once I implement your motor (thanks again for that! You’re a genius!) this has trouble deciding where to set the destination, since it has no graph or navmesh to place it on anymore. It just ends up putting the destination somewhere around 0,0,0, which causes some problems when the character tries to move toward it

    So in other words, if you’re not sick of helping me yet, is there a way I could change the above script to try to set the destination (within the wander distance) on the unity navmesh?

    Thanks so much again, you’re the best.

    #38644

    ILoFoSho
    Participant

    Hey everybody! I figured out how to fix the above script to use the navmesh appopriately. I can’t imagine anybody having the same specific problem as I did, but I’ll post the solution anyway in case anybody can get something useful out of studying the scripts.

    With the help of this unity answers page about creating Vector3’s on Unity’s navmesh:

    http://answers.unity3d.com/questions/475066/how-to-get-a-random-point-on-navmesh.html

    I just edited and implemented the above script to this:

    using UnityEngine;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using RAIN.Action;
    using RAIN.Core;
    using RAIN.Representation;
    using RAIN.Navigation;
    [RAINAction("Choose Wander Position For Unity Nav Mesh")]
    public class ChooseWanderPositionUnityNavMesh : RAINAction
    {
    	/// <summary>
    	/// Public Expressions are editable in the Behavior Editor
    	/// WanderDistance is the max range to use when picking a wander target
    	/// </summary>
    	public Expression WanderDistance = new Expression();
    	/// <summary>
    	/// Public Expressions are editable in the Behavior Editor
    	/// StayOnGraph is a boolean (true/false) that indicates whether the wander target must be on the nav graph
    	/// </summary>
    	//public Expression StayOnGraph = new Expression();
    	/// <summary>
    	/// Public Expressions are editable in the Behavior Editor
    	/// WanderTargetVariable is the name of the variable that the result will be assigned to
    	/// *Don't use quotes when typing in the variable name
    	/// </summary>
    	public Expression WanderTargetVariable = new Expression();
    	/// <summary>
    	/// The default wander distance to use when the WanderDistance is invalid
    	/// </summary>
    	private float _defaultWanderDistance = 10f;
    	public override ActionResult Execute(RAIN.Core.AI ai)
    	{
    		if (!WanderTargetVariable.IsVariable)
    			throw new Exception("The Choose Wander Position node requires a valid Wander Target Variable");
    		float tWanderDistance = 0f;
    		if (WanderDistance.IsValid)
    			tWanderDistance = WanderDistance.Evaluate<float>(ai.DeltaTime, ai.WorkingMemory);
    		if (tWanderDistance <= 0f)
    			tWanderDistance = _defaultWanderDistance;
    		Vector3 tDirection = UnityEngine.Random.insideUnitSphere * tWanderDistance;
    		tDirection += ai.Body.transform.position;
    		Debug.Log (tDirection);
    		NavMeshHit hit;
    		NavMesh.SamplePosition(tDirection, out hit, tWanderDistance, 1);
    		Vector3 tDestination = hit.position;
    		/*if (StayOnGraph.IsValid && (StayOnGraph.Evaluate<bool>(ai.DeltaTime, ai.WorkingMemory)))
    		{
    			if (NavigationManager.Instance.GraphForPoint(tDestination, ai.Motor.MaxHeightOffset, NavigationManager.GraphType.Navmesh, ((BasicNavigator)ai.Navigator).GraphTags).Count == 0)
    				return ActionResult.FAILURE;
    		}*/
    		ai.WorkingMemory.SetItem<Vector3>(WanderTargetVariable.VariableName, tDestination);
    		return ActionResult.SUCCESS;
    	}
    }

    So there ya go! If anybody runs into something like I did, hopefully this page will help them out.

    Once again, Sigil, THANK YOU! You’re a lifesaver!

    #38673

    Martin Cmar
    Participant

    here is my example that works with basic motor and act strange with this new motor. When I run this scene, the actor goes straight to the obstacle and then stops. I hoped when we replaced the motor, it will now work for everything movement-related. or does it work only in some special cases?

    I have made a package containing RAIN free and my test scene demonstrating this problem.

    https://mega.co.nz/#!MIc1WDZK!HDHA1sDiioENSnTTVBJKzIECUKrgsw00pRfAP_6qwJs

    edit: but the navigation surely works. when you drag the second waypoint to the other side of the obstacle, the actor goes around. it looks like he just simply dont know right what to follow

    • This reply was modified 1 year, 2 months ago by  Martin Cmar.
    • This reply was modified 1 year, 2 months ago by  Martin Cmar.
    • This reply was modified 1 year, 2 months ago by  Martin Cmar.
    #38683

    Sigil
    Keymaster

    Here is an updated motor that should fix that problem. It also fixes a couple things for off graph movement and 3d movement/rotation, which I don’t think works with the NavMeshAgent straight out of the box.

    // Newer version further down
    • This reply was modified 1 year, 1 month ago by  Sigil. Reason: removed code
    #38685

    Sigil
    Keymaster

    I will continue to update this motor as I can. Just come back with problems or issues.

    #38777

    Martin Cmar
    Participant

    thanks sigil.
    I have checked the test scene I have posted before and it worked. and if I add multiple agents, they are of corse avoiding each other, which was the primary goal

    BUT

    I have tried to change the path, and similiar problem appears. When the AI actor is moving along the route for the very first time, he skips one node and go immediately to the next. But when he goes back (I have ping pong patrol enabled), he does not skip anything and go through every node correctly. So there has to be one last minor issue that causing this strange behavoir.

    As before, I have uploaded the package containing everything needed to test it. thanks
    https://mega.co.nz/#!UdFAEZbI!U0bPktDrfud8kjuYvDiN51H-DxMTf0q3azPZXK8nlBo

    #38779

    ck
    Participant

    There’s an issue with the motor where if the Move action gets interrupted by a constraint condition but the agent is not at the target position, the NavMeshAgent keeps moving towards it regardless.

    Also, would it be possible to subclass the MecanimMotor to use the NavMeshAgent and to somehow pass the Speed & RotationSpeed values back to Mecanim? Thanks!

    #38899

    Martin Cmar
    Participant

    have you any clues how to fix my issue?

    #38905

    Sigil
    Keymaster

    Sorry about that, I lost track of this thread and kept meaning to come back to it. I’ll take a closer look at the couple issues mentioned and get back tonight (I pinned the email so I won’t miss it).

    #38914

    Sigil
    Keymaster

    Edited: Fixed both problems, so never mind the previous post. The main changes are in the UpdateMotionTransforms and ApplyMotionTransforms where I copy positions and orientation over, and set acceleration to zero temporarily. When Move or when the ApplyMotionTransforms are called at the end of the frame I put the acceleration back.

    Let me know how it works.

    // Newer version further down (or next page)
    • This reply was modified 1 year, 1 month ago by  Sigil. Reason: fixed it
    • This reply was modified 1 year, 1 month ago by  Sigil. Reason: removed code
    #38944

    ck
    Participant

    Hey Sigil,

    I’m still experiencing the same issue with the latest version of your motor script where the navMeshAgent continues to move the character even if the Move action is not being called. Could you take another look at it when you have a chance?

Viewing 15 posts - 1 through 15 (of 26 total)

You must be logged in to reply to this topic.