- Home /
NavMesh flee. Ai flee from player.
This script makes ai fallow player :
var player: Transform;
function Start(){
player = GameObject.FindWithTag("Player").transform;
}
function Update()
{
GetComponent(NavMeshAgent).destination = player.position;
}
Now,how can i make AI RUN AWAY From Player. Just Run away from player with navmesh. I know i have to get player vector and then i have to make an Ai to move there. Or maybe there is an other option? Help me out smart people!
P.S. Please show your examples in script,thanks.
This will get a reverse lookat
transform.rotation = Quaternion.LookRotation(transform.position - player.position);
But now we need to get a random point along that line, give me a bit of time and I'll get back to you. $$anonymous$$ay not be tonight (well tonight where I am!)
Oh and look into Nav$$anonymous$$esh.SamplePosition which you can give a Vector3 to and it'll find the nearest point on a Nav$$anonymous$$esh to that point.
Just adding that as it is getting late where I am so unlikely to be able to get the code you need soon.
Answer by Mmmpies · Jan 06, 2015 at 07:59 PM
Right sorry for the delay @Marks981 (work got in the way), this isn't perfect although you may not worry about the drawback which I'll explain after posting the code. Oh and there's a lot of comments in there so the actual code is a lot smaller:
using UnityEngine;
using System.Collections;
public class NavMeshRun : MonoBehaviour {
private Transform player;
private NavMeshAgent myNMagent;
private float nextTurnTime;
private Transform startTransform;
public float multiplyBy;
// Use this for initialization
void Start () {
player = GameObject.FindGameObjectWithTag ("Player").transform;
myNMagent = this.GetComponent<NavMeshAgent> ();
RunFrom ();
}
// Update is called once per frame
void Update () {
// used for testing - can be ignored
if(Time.time > nextTurnTime)
RunFrom ();
}
public void RunFrom()
{
// store the starting transform
startTransform = transform;
//temporarily point the object to look away from the player
transform.rotation = Quaternion.LookRotation(transform.position - player.position);
//Then we'll get the position on that rotation that's multiplyBy down the path (you could set a Random.range
// for this if you want variable results) and store it in a new Vector3 called runTo
Vector3 runTo = transform.position + transform.forward * multiplyBy;
//Debug.Log("runTo = " + runTo);
//So now we've got a Vector3 to run to and we can transfer that to a location on the NavMesh with samplePosition.
NavMeshHit hit; // stores the output in a variable called hit
// 5 is the distance to check, assumes you use default for the NavMesh Layer name
NavMesh.SamplePosition(runTo, out hit, 5, 1 << NavMesh.GetNavMeshLayerFromName("Default"));
//Debug.Log("hit = " + hit + " hit.position = " + hit.position);
// just used for testing - safe to ignore
nextTurnTime = Time.time + 5;
// reset the transform back to our start transform
transform.position = startTransform.position;
transform.rotation = startTransform.rotation;
// And get it to head towards the found NavMesh position
myNMagent.SetDestination(hit.position);
}
}
The downside is this, I couldn't find a way to get the forward information to be away from the player without pointing the object in that direction first. Now this might not bother you, having the enemy/creature suddenly face away from the player might look fine in your game, in which case not a problem.
I tried recording the start transform and once we get the hit point on the navmesh setting the position and rotation back to the startTransform, but it does appear to glitch slightly when finding the position.
It might just be that I'm using an empty scene with cubes so it's more obvious on screen.
Give it a shot anyway.
Hi buddy,im impressed,you have a very good knowledge at scripting complicated and tricky scripts like this one. Your script is just what i need,its enough for me,whatever its glitchy or not,i still can modify it and learn from it. I would never have imagined that this way of doing it. Thanks man,script is very good and it works very nice,i very appreciate your help. Good luck to you mate :) Thanks for your time and help.
@$$anonymous$$arks981 no problem, and thanks for the good comments, if you don't want the record start point it gets less complex all you really need is this:
transform.rotation = Quaternion.LookRotation(transform.position - player.position);
Vector3 runTo = transform.position + transform.forward * multiplyBy;
Nav$$anonymous$$eshHit hit;
Nav$$anonymous$$esh.SamplePosition(runTo, out hit, 5, 1 << Nav$$anonymous$$esh.GetNav$$anonymous$$eshLayerFromName("Default"));
myN$$anonymous$$agent.SetDestination(hit.position);
which is a lot more readable.
Thanks buddy,i already figured it out :) and thanks again man for your help,best wishes to you :)
Hi, I know this must have been a really old Post but, I tried your code and it only moves my character on a random speed to the hit destination. I tried adding speed to it but, doesn't work. Please, how do you change the speed and also make enemy move slow when the range is far?
Thanks mate. This is just what I needed. $$anonymous$$aybe sometime you could help with a script I need for a light that turns on and turns off at certain times. It would help with lights at my campsite. Thanks for the run away script!
Answer by waterlight_ · Aug 03, 2017 at 10:37 AM
You can use vectors as well. This is an example of a script attached to an animal;
NavMeshAgent agent;
[SerializeField] Transform Player;
Int multiplier = 1; // or more
float range = 30;
Void start() {
agent = GetComponent<NavMeshAgent>();
}
Void Update() {
Vector3 runTo = transform.position + ((transform.position - Player.position) * multiplier);
float distance = Vector3.distance(transform.position, Player.position);
if (distance < range) agent.SetDestination(runTo);
}
Answer by GraviterX · Jan 04, 2015 at 11:46 PM
I would make an empty gameobject somewhere else in the scene away from your player and have it run to that.
This is a viable option depending on what you want to achieve, say you have a timid animal (chicken/rabbit) even if it moves in a certain range for random movement if a player/NPC gets too close it might run to the nearest bolt hole.
If you want the run position to be random you could make several game objects around the scene and use random.range in your enemy AI code so it can choose one to go to at random.
Answer by justinsykes2006 · Apr 20 at 07:43 PM
This is an edit of waterlight_'s code. I added a bit more "randomness" to the way it moves, which makes it more realistic NavMeshAgent agent; [SerializeField] Transform Player; int multiplier = 1; // or more float range = 22;
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
void Update()
{
Invoke(nameof(Run),Random.Range(2, 4));
}
void Run()
{
Vector3 runTo = transform.position + ((transform.position - Player.position + new Vector3(Random.Range(-12, 12), 0, Random.Range(-15, 12)) * multiplier));
float distance = Vector3.Distance(transform.position, Player.position);
agent.speed = Random.Range(7.5f, 11f);
if (distance < range) agent.SetDestination(runTo);
}