News Forums General Discussion Random Direction Grazing Behaviour

This topic contains 14 replies, has 5 voices, and was last updated by  prime 1 year, 1 month ago.

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

    nomax5
    Participant
    I am trying to create a random direction random, distance code for my mobs and 
    I was wondering if anyone had any ideas on the best way to go about this with new Rain.
    Basically 
    Get a random direction
    Get a random distance (within min max parms)
    	If the destination is navigable 
    		move to destination
    I did it before with code ( and a lot of help) but so much has changed 
    I'm thinking more can be done in the BT.
    Also the code is in old unity projects and I cant remember if I screwed up the 
    code or it still works 
    I'll paste my deer wandering code below: 
    it makes my deer's wander and graze then change direction and do it 
    again, or it used to lol. 
    Any help or ideas greatly appreciated
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using RAIN.Core;
    using RAIN.Motion.Instantaneous;
    using RAIN.Belief;
    using RAIN.Action;
    public class deerWander : Action
    {
        public float distance = 30f;
        public float radius = 25f;
        public float slideDegrees = 180f;
        public float tToTarget = 0.5f;
        public float cEnoughRadius = 0.5f;
        private SB_Face look;
        private SB_Seek move;
        private SB_Wander sb_wander;
        private SB_Seek sb_seek;
        private SB_LookWhereYoureGoing sb_lookGoing;
        Kinematic targetK;
    	public deerWander()
    	{
    		actionName = "deerWander";
            targetK = new Kinematic();
            sb_seek = new SB_Seek();
            sb_lookGoing = new SB_LookWhereYoureGoing(0f, 1f, 1f, 5f);
    	}
    	public override ActionResult Start(Agent agent, float deltaTime)
    	{
            targetK.Position =  new Vector3 
                (agent.Avatar.transform.position.x + Random.Range(-20f, 20f), 
                agent.Avatar.transform.position.y, 
                agent.Avatar.transform.position.z + Random.Range(-20f, 20f));
            targetK.Orientation = Vector3.zero;
            targetK.Velocity = Vector3.zero;
    		return ActionResult.SUCCESS;
    	}
    	public override ActionResult Execute(Agent agent, float deltaTime)
    	{
            //if the AI has taken damage or is in combat stop wandering
            if (agent.actionContext.GetContextItem<float>("takeDamage") > 0f ||
                agent.actionContext.GetContextItem<float>("inCombat") > 0f)
            {
                return ActionResult.SUCCESS;
            }
            //show a line for debugging purposes to the random destination
            Debug.DrawLine(agent.Avatar.transform.position, targetK.Position);
            //Steer toward the location
            Steering s = sb_seek.Steer(agent.Kinematic, targetK);
            Steering s2 = sb_lookGoing.Steer(agent.Kinematic);
            //move to the destination
            agent.Kinematic.SetVelocity(s.Velocity/10, s.AngularVelocity + s2.AngularVelocity);
            //check if we reached the destination
            float distance = Vector3.Distance(agent.Avatar.transform.position, targetK.Position);
            if (distance < 1.0f)
            {
                return ActionResult.SUCCESS;
            }
            else
            {
                if (agent.actionContext.GetContextItem<GameObject>("EnemyFound") != null)
                {     
                    return ActionResult.SUCCESS;
                }
                else {
                    return ActionResult.RUNNING;
                }
            }
    	}
    	public override ActionResult Stop(Agent agent, float deltaTime)
    	{
    		return ActionResult.SUCCESS;
    	}
    }
    • This topic was modified 1 year, 1 month ago by  nomax5.
    • This topic was modified 1 year, 1 month ago by  nomax5.
    • This topic was modified 1 year, 1 month ago by  nomax5.
    • This topic was modified 1 year, 1 month ago by  nomax5.
    • This topic was modified 1 year, 1 month ago by  nomax5.
    #4971

    Hank
    Participant

    I was working on the same thing. I’m totally new to RAIN (and fairly new to Unity) so I’m learning from the ground up.

    I was able to get a simple random wander to work. Here’s what I did:

    In the RAIN UI add a variable that is a GameObject. Then make the value the GameObject that contains the AI and will do the wandering. I named this variable “Avatar”.

    My behavior tree is very simple:

    One Parallel Container with a Custom Action and a Move action. In the Move action the Move Target is set to the variable “directionVector.” The Custom Action then runs the following script which is based on the C# template from RAIN:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using RAIN.Core;
    using RAIN.Action;
    [RAINAction]
    public class RandomWalk : RAINAction
    {
    	public Vector3 directionVector;
            //Distance to wander after each success or failure of Move action
    	float distanceToWander = 10;
    	//GameObject that is going to wander and contain AI
    	GameObject positionAvatar;
    	//Expression strength = new Expression();
        public RandomWalk()
        {
            actionName = "RandomWalk";
        }
        public override void Start(AI ai)
        {
    		base.Start(ai);
    		//Get GameObject that Holds AI - GameObject must be set as Variable in RAIN UI
    		positionAvatar = ai.WorkingMemory.GetItem<GameObject>("Avatar");
    		//Set Random Direction
    		Vector2 newVector = Random.insideUnitCircle;
    		directionVector.x = newVector.x;
    		directionVector.z = newVector.y;
    		//Set Length of Vector
    		directionVector = directionVector * distanceToWander;
    		//Set Position to Move to relative to Current Position
    		directionVector = positionAvatar.transform.position + directionVector;
                    //Set variable/location in move block in BT 
    		ai.WorkingMemory.SetItem<Vector3>("directionVector", directionVector);
        }
        public override ActionResult Execute(AI ai)
        {	
    		return ActionResult.SUCCESS;
        }
        public override void Stop(AI ai)
        {
            base.Stop(ai);
        }
    }

    The result is a very simple wander. I’d still like to modify it so that the new direction vector is within some range of the current direction so that the wandering looks a little more realistic… But at least the basics are in place.

    #4972

    Hank
    Participant

    A little follow-up.

    This code/setup seems to work great with no nav mesh (on flat empty terrain), but if I place the wandering gameObject on a nav mesh it stops after a seemly random number of cycles. Sometimes it will wander to 3-4 position and then freeze sometimes it’ll wander to 7 or 8 position before freezing.

    #4976

    prime
    Keymaster

    I’ll look into your example further in a little while. However, there is no need to create the “Avatar” variable to hold the GameObject for the AI. The AI already gives you that in AI.Body.

    #4982

    Hank
    Participant

    After playing around a little more I saw AI.Body and realized the Avatar variable was just extra. Living and learning!

    The problem with the gameObject freezing seems to occur when the new location to move to is outside of the nav mesh and or inside the nav mesh but a location that is unreachable. I was going to see if I could check that the location was inside the nav mesh and if not I’d select a new point. (I’m very new to RAIN and Unity so small things are still taking awhile.)

    #4999

    Hank
    Participant

    I did two things to “fix” my approach. First I added a timer to the BT that returns FAILURE. In case the new random position was “unreachable” this allowed the BT to restart. This was necessary as the Move action was not returning a FAILURE even if there was no path on the nav mesh to the new position - I feel like I’m missing something?

    I also updated the script to include a max angle turn. If this max angle is small there is a chance the object can get stuck at the edge of the nav mesh. I added a random chance that the turn angle can be large this serves to prevent the object from getting stuck.

    My code as of now can be found at http://pastebin.com/rGmbiCYA

    • This reply was modified 1 year, 1 month ago by  Hank.
    • This reply was modified 1 year, 1 month ago by  Hank.
    • This reply was modified 1 year, 1 month ago by  Hank.
    • This reply was modified 1 year, 1 month ago by  Hank.
    #5054

    WolfWithin
    Participant

    I would try your script, you can explain to me how should I use it? Step by step, I am very newbie in RAIN.
    Thank you very much.

    #5058

    Hank
    Participant

    @WolfWithin
    I wrote up an explanation here. It assumes you have watched and understood the basic tutorial from Rival Theory - so you know how to make an GameObject into an AI and how to work with the Behavior Tree Editor. The explanation has images showing you how to set up the Behavior Tree and how the variables in the RAIN UI should be set. There is also a link to a more up to date script then what I posted here.
    -
    What it doesn’t explain is where to put the script. When you create the behavior tree and add the Custom Action (and create a custom class) a new template will be created in a project folder AI > Actions. Replace the template with my code.
    -
    Let me know if you encounter any problems.

    • This reply was modified 1 year, 1 month ago by  Hank.
    #5084

    WolfWithin
    Participant

    @Hank
    Thank you very much for your help! I’ve seen all the tutorials and I can do simple AI. I will try your custom action.

    #5089

    nomax5
    Participant

    I wonder if there is a way to pick a point on the navgrid and figure out if it’s possible to navigate to that location in code.
    Rain must do it to calculate routes.

    #5090

    Hank
    Participant

    @nomax5 There must be a way. I’d love to know how.

    #5098

    Aaron Mueller
    Participant

    @nomax5, @Hank,

    In the API docs there is RAIN.Navigation.Pathfinding.RAINPath. (Sorry, there doesn’t appear to be a way to link directly to that item in the API docs).
    -
    You pass it a vector 3 position, a max number of steps and an out variable that produces a path to that Vector3 position if it’s valid.
    -
    I haven’t done any of this myself, but it seems that this might get you going in the right direction.

    #5108

    prime
    Keymaster

    @nomax5 - two things for you:

    RAINNavigator.OnGraph(Vector3 aPosition) will tell you if a point is on the NavigationGraph.

    RAINNavigator.GetPathTo(Vector3 position, int maxPathfindSteps, out RAINPath path) will calculate the path directly in a single step, up to maxPathfindsteps calculations.

    Setting the Navigator.pathTarget to your destination and the repeatedly calling Navigator.GetPathToMoveTarget(out RAINPath path) until it returns true will give you a version you can spread across multiple frames. You check that the path is not null and path.IsValid to make sure you have a valid path.

    #5219

    Hank
    Participant

    @prime Been a busy few days at my day job, just finally had time to read your reply.
    -
    I follow what you are saying (I think). I want to check if the current position and the desired destination is on the nav mesh I’ve used the code - checking both allows me to stay on or stay off a nav mesh:

    curPosOnPath = RAINNavigator.OnGraph(ai.Body.transform.position);
    nextPosOnPath = RAINNavigator.OnGraph(directionVector);

    -
    Where directionVector is the desired position. I get the error:
    -
    error CS0120: An object reference is required to access non-static member RAIN.Navigation.RAINNavigator.OnGraph(UnityEngine.Vector3)
    -
    I can’t seem to crack this one…

    #5224

    prime
    Keymaster

    You want

    curPosOnPath = ai.Navigator.OnGraph(ai.Body.transform.position);
    nextPosOnPath = ai.Navigator.OnGraph(directionVector);
Viewing 15 posts - 1 through 15 (of 15 total)

You must be logged in to reply to this topic.