I have an agent and I want it to get to a destination.
However! I want to avoid enemies while doing so, meaning if an enemy is in the path it will change it.
I am using premade locations that I want my paths to go through for that.
if an enemy is near a location I am finding a different one.
My question is: How can I define a path to through certain “points”(locations)
And if there is a way to do without setting up points, but just checking if an object is in the path and recalculating a new path around/away from the object, how can you do that?
There are many ways to do this, but the simplest I can think of is just to set the destination to be your first point, then replace the destination with the next point after it is reached. Somewhat surprisingly, detecting that you have reached your destination isn’t built into the Nav system. Googling suggests that many people just put a GameObject with a Collider at the destination and wait for OnCollisionEnter. You could also use OffMeshLink objects, but I think that would be more complicated than it was worth.
Changing to another path when an enemy blocks you would be more complicated. The Nav system will look for ways around an obstacle (see the NavMeshObstacle class), but that’s because it’s still trying to find a path to the same destination. You can use NavMesh.CalculatePath and check the status of the resulting path to know if there is a way left to get to the destination, or if it is fully blocked. But, Unity says that’s an expensive method and you shouldn’t run it over and over.
Perhaps you can achieve the effect you are looking for with raycasts from your player to your enemy. If the player can see the enemy (and, one assumes, vice versa), then maybe the player would try to move to some intermediate point where it is hidden from the enemy. This would get complicated pretty fast, especially if you wanted to avoid cycling repeatedly between hiding-here-hiding-there-and-back-again, but it might be pretty cool if you could get it work.
Question: What’s left for the player to do if you are using the Nav system to control the player’s location?
First, you can check if the path is done by agent.path.status (Or at least, by looking at the status enum it gives this impression)
Second, a path has a list of corners and in the meanwhile, I’ve had a little time to mess with them, tho you can only read them so I’m not sure what I can do with that… tho I can check if the enemy is in between any of the corners, aka, in the path’s way.
I cannot use NavMeshObstcle for the enemy for a simple reason, I only want the runner to avoid them not everyone else.
My second solution is complex raycasting to determine the enemy, walls, etc.
this ‘fleeing’ has two purposes:
Run away from a chaser
Get to a location avoiding the chaser
For example, in a plain open space I rather just run away.
However, if I am in a closed building the logical solution would be finding a way out without encountering the chaser.
And for your question: this isn’t for the player this is for my AI behaviour, sorry if I made it unclear.
Edit
I’ll add, even if you could make an obstacle that would affect only one agent(the runner)
You’d need to make it way bigger than the enemy itself, the logic is that if someone chases you, you want to keep a fine distance away, especially if they hold a weapon with a certain range which you’d probably like to avoid
That refers to whether the path reaches the goal, doesn’t reach the goal, or is invalid. It doesn’t tell you anything about the agent. (Or is that what you meant?)
I’d explore this approach for a while. The Nav system is interesting, but I think it is kind of limited and, for what you are doing, would be more of a challenge to use than coming up with something of your own.
I love Unity, but it is my suspicion that some of what’s in the API is there to make life easy for people with limited programming skills. For example, Nav uses the A* pathfinding algorithm. I would have to guess that a computer programmer could enjoy an entire successful career without ever knowing what that was. With the Nav system, you don’t have to, and you can still make NPCs do some impressive things. But if you do know what it is, you are probably in a position to create custom classes that will do a better job for your game than Nav can (or, even if Nav can do what you want, your own custom classes will make getting that result easier than if you tried to squeeze it out of Nav).
Raycasting looks promising to me. Let us know how it works out for you.
I tried coming up with a raycasting set up in the meanwhile… for now, it’s something like this:
(Pseudo code)
------------------------------ #raycasts
A line straight forward => check for wall
Lines to left and right => check for walls
Sphere => check for chaser in range
Raycast from every result in the sphere to check if a collider separates or not
and collecting only the ones who are not blocked by a collider
#behaviour
if a wall is seen upfront look at the sides to determine where to go.
If both are clear go for a random option(stress close call)
if the chaser in the sphere get direction and attempt to move the other way ------------------------------
My biggest problem with that approach is its very base… Colliders, NavMesh doesn’t need colliders, it doesn’t mean I cannot add them, but using it means I don’t only need it, but let an entire system rely on it…
But either way, what do you think of it so far? I mean… it deffo needs upgrading, but I am not sure what to do for now except for attempt to implement it.
It’s worth trying. Yes, you’ll need to add some Colliders. That doesn’t seem like a big issue to me.
I’d suggest creating a very simple scene with a few cubes and so forth, and try this in a very uncomplicated environment. Get yourself a system that works in situations where you are confident you know what it should be doing, and where you can test specific behaviors you want to produce. Once that;s working to your satisfaction, add it to your game.
You can change the destination whenever you want to, and the path will change accordingly. Again, I would try some experiments in a very pristine context, with only a few objects. See what happens.