Flee without using navmesh

Hi I’m making an underwater survival game and i am having trouble making my AI flee from approaching other AI (e.g my fish fleeing sharks). Is their anyway to make AI flee without using a Navmesh ?

What is the problem here? Move your fish AI in any direction away from the shark AI and that’s it.

Sorry I will explain in more depth. I have fish that eat small fish (this is a 3D game) and while it’s eating a fish carcass if a shark approaches it I want the fish to leave the small fish and flee. So my fish searches, attacks but flees from larger sharks?

Last time, I answered one of your threads, didn’t you say that you were using some software called Mercuna for navigation? The website makes it look pretty sophisticated. Does that not provide a solution already?

I am using Mercuna but it doesn’t have a flee node. When i add flee to behavior designer the fish just stays still when it is meant to be fleeing. This is my flee node I have created with shows up in behavior designer but dosen’t seem to do anything ?

[Tooltip("The agent has fleed when the magnitude is greater than this value")]
        public SharedFloat fleedDistance = 20;
        [Tooltip("The distance to look ahead when fleeing")]
        public SharedFloat lookAheadDistance = 5;
        [Tooltip("The GameObject that the agent is fleeing from")]
        public SharedGameObject target;
        [Tooltip("The tag of the object that we are searching for")]
        public SharedString targetTag;

        private bool hasMoved;

        public override void OnStart()
        {
            base.OnStart();

            hasMoved = false;

            SetDestination(Target());
        }

        // Flee from the target. Return success once the agent has fleed the target by moving far enough away from it
        // Return running if the agent is still fleeing
        public override TaskStatus OnUpdate()
        {
            if (Vector3.Magnitude(transform.position - target.Value.transform.position) > fleedDistance.Value)
            {
                return TaskStatus.Success;
            }

            if (HasArrived())
            {
                if (!hasMoved)
                {
                    return TaskStatus.Failure;
                }
                if (!SetDestination(Target()))
                {
                    return TaskStatus.Failure;
                }
                hasMoved = false;
            }
            else
            {
                // If the agent is stuck the task shouldn't continue to return a status of running.
                var velocityMagnitude = Velocity().sqrMagnitude;
                if (hasMoved && velocityMagnitude <= 0f)
                {
                    return TaskStatus.Failure;
                }
                hasMoved = velocityMagnitude > 0f;
            }

            return TaskStatus.Running;
        }

        // Flee in the opposite direction
        private Vector3 Target()
        {
            return transform.position + (transform.position - target.Value.transform.position).normalized * lookAheadDistance.Value;
        }

        // Return false if the position isn't valid on the NavMesh.
        protected override bool SetDestination(Vector3 destination)
        {
            if (!SamplePosition(destination))
            {
                return false;
            }
            return base.SetDestination(destination);
        }

        private bool SamplePosition(Vector3 destination)
        {
            throw new NotImplementedException();
        }

        // Reset the public variables
        public override void OnReset()
        {
            base.OnReset();

            fleedDistance = 20;
            lookAheadDistance = 5;
            target = null;
        }
    }

What does base.SetDestination do? It looks like your node should always throw that NotImplementedException, though, because you are always calling SamplePosition in set destination.

was trying to get it to basically turn around and flee to opposite direction away from other ai then back to wander?

In your behavior tree, are you actually setting the target to anything?

I am setting the target as the object i want it to flee from

Ok, but what does base.SetDestination do? what is SamplePosition supposed to do?

I’m trying to set a destination to behind so it turns and flees but not sure how set destination ?

Here’s one way to choose a destination based on some simple vector math:

Your destination should be a point that’s a certain distance away from the predator. in order to get a direction that’s away from the predator, you can use the formula:

Vector3 awayDirection = prey.transform.position - predator.transform.position;

Now you need to create a point that is a certain distance in that direction. lets say you have a float called fleeDistance that is the distance that you want the prey to flee. Then a the destination could be:

Vector3 fleeDestination = prey.transform.position + (awayDirection.normalized * fleeDistance);

Note that we need to normalize the awayDirection because the magnitude of away direction is just arbitrary and we don’t want it to affect the formula.

does that make sense?

this is my tree

ah right do i need to create empty game object for a flee to ?

That would depend on whether your navigation software needs an object or if it just needs a position vector.

ah right tried that code but It says i need an assembly reference?

 private bool hasMoved;
        public float fleedistance;
        private object prey;
        private object predator;

prey and predator should be type GameObject.

Just going to check this script but just want to make sure i have everything correct ?

private bool hasMoved;
        public float fleedistance;
        private GameObject prey;
        private GameObject predator;

        public override void OnStart()
        {
            base.OnStart();

            hasMoved = false;

            SetDestination(Target());
        }

        // Flee from the target. Return success once the agent has fleed the target by moving far enough away from it
        // Return running if the agent is still fleeing
        public override TaskStatus OnUpdate()
        {
            if (Vector3.Magnitude(transform.position - target.Value.transform.position) > fleedDistance.Value)
            {
                return TaskStatus.Success;
            }

            if (HasArrived())
            {
                if (!hasMoved)
                {
                    return TaskStatus.Failure;
                }
                if (!SetDestination(Target()))
                {
                    return TaskStatus.Failure;
                }
                hasMoved = false;
            }
            else
            {
                // If the agent is stuck the task shouldn't continue to return a status of running.
                var velocityMagnitude = Velocity().sqrMagnitude;
                if (hasMoved && velocityMagnitude <= 0f)
                {
                    return TaskStatus.Failure;
                }
                hasMoved = velocityMagnitude > 0f;
            }

            return TaskStatus.Running;
        }

        // Flee in the opposite direction

        public Vector3 AwayDirection { get => AwayDirection; set => AwayDirection = value; }
        public Vector3 FleeDestination { get; set; }

        private Vector3 Target()
        {
            return transform.position + (transform.position - target.Value.transform.position).normalized * lookAheadDistance.Value;
        }

        // Reset the public variables
        public override void OnReset()
        {
            base.OnReset();

            fleedDistance = 20;
            lookAheadDistance = 5;
            target = null;
        }
    }

Not sure. I’m having some difficulty following that code.

which part is confusing?