Vector2.MoveTowards Player/Target position PLUS run further

Hello,

hopefully this makes sense…

what I have going right now, is a NPC running away from the player, but technically using the MoveTowards function:

transform.position = Vector2.MoveTowards(transform.position, target.position, -moveSpeed * Time.deltaTime);

the Target is the player, Transform is of course the object/NPC, however I want it to run further than the target, which I have it running backwards the way i want -moveSpeed float variable, however it will just run for a certain amount of distance… I do have a “Circle” that checks if overlaping:

runAwaySafe = Physics2D.OverlapCircle(transform.position, checkrunAwaySafeRadius, WhatIsPlayer);

however I want it to be able to reach it, and then… or else… so I am trying to figure that part out…

hopefull this makes sense… if not maybe picture below may help?

NPC is the blue, black is the player, if player goes inside the OverLapCircle, then NPC runs till it gets to the Green Safe or the runAwaySafe… again I have the overlap circle:

transform.position = Vector2.MoveTowards(transform.position, target.position, -moveSpeed * Time.deltaTime);

but not sure what I should put… I tried this:

            if (runAwaySafe)
            {
                Vector2 dir = target.position - transform.position;
                transform.position = Vector2.MoveTowards(transform.position, target.position, -moveSpeed * Time.deltaTime);

                Quaternion toRotate = Quaternion.LookRotation(Vector3.forward, -dir);
                transform.rotation = Quaternion.Lerp(transform.rotation, toRotate, RunSpeed);
            }

BUT… runs away… but something maybe the target.position i need to add or maybe something else? maybe change it entirely?? not sure, any thoughts?

This is a hard problem to solve in the general case because there’s so many ways for it to fail.

For instance what if the bad guy runs into a wall, or runs off the edge of the level? Now the AI has to recognize that it TRIED to run away but got stuck so you don’t want it to just sit there in sheer terror running against the wall until the player comes up and whacks him from behind. That might work for some games, but for most it is undesirable.

One approach is to produce a “run away!” destiation for the enemy that is AWAY from the player by some amount. In other words, player position + vector to enemy + go some more in the same(-ish) vector direction and then try to go there via your normal navigation process.

Another approach that shooter games use is to populate the level with lots of “take cover” locations, basically invisible GameObjects placed throughout the level near doorways, around pillars, behind boxes, etc. When the enemy panics he asks for the ten nearest ones and iterates them all, looking for ones that are out of line of sight (if that matters, eg, you have projectile weapons), or just ones that are the farthest away from the player.

LOL “Sheer Terror” so true, nope all good cases you pointed out thank you Kurt… I think I will go about that route in creating “Safe places” to MoveTowards, that will work… thanks :slight_smile:

most likely, just put some empty game objects, and depending on the angle the player comes close to contact, they will run to that game object

Remember also to favor locations that are in a direction away from the player.

This can help avoid the enemy trying to run past the player (eg, getting really close to him) when he’s trying to get to what he considers the best safe spot, which just happens to be on the other side of the player from him. :slight_smile:

Also, generally simpler is better… go with the minimum setup that gives you acceptable play, and refine it from there with small changes. The more complex a setup you make the harder it becomes to reason about why it behaves in a mysterious way.

1 Like