- Home /
AI wandering script?
I am trying to make a script to make an object wander around. So far I have this:
var speed : int= 5; var wayPoint : Vector2;
function Start() { InvokeRepeating("Wander", 2, 20); }
function Wander() { var wayPoint : Vector2= Random.insideUnitCircle *47; Debug.Log(wayPoint); }
function Update() { transform.LookAt(wayPoint); rigidbody.AddRelativeForce(Vector3.forward * speed); }
This makes the object move to the position I want but my problem is that since it's a vector2 it operates between the x and y axis. I want my object to move 2 dimensionally (between the x and z axis). When I leave the var wayPoint undefined when the game first starts the entire script doesn't work. Why is this? additionally I tried to make a while statement and then replaced it with an if statement saying that while(or if) the object was not dead that it would "Wander". Any help is appreciated. Should the function Update() be a Fixed Update instead?
Answer by spinaljack · Jul 22, 2010 at 01:15 AM
FixedUpdate should be reserved for physics related functions.
You need to make wayPoint a global variable by declaring it outside of the function, put it at the top of your script, leaving it undefined obviously means that variable has no meaning and wont compile if you tried to use it in a function later e.g.
var wayPoint : Vector3;
function Start(){ Wander(); }
You can also use Radom.insideUnitSphere instead and then set the y variable to whatever height your floor is e.g.
function Wander(){
wayPoint = Random.insideUnitSphere*47;
wayPoint.y = 0;
}
Instead of using invoke you could simply call Wander after you've reached the waypoint and the character is still alive. e.g.
var isAlive : boolean = true;
function Update(){ if((transform.position - wayPoint).magnitude < 0.5 && isAlive){ Wander(); } }
EDIT:
Here's your working code...
var Speed= 10; var wayPoint : Vector3;
function Start(){ //initialise the target way point Wander(); }
function Update() { // this is called every frame // do move code here transform.position += transform.TransformDirection(Vector3.forward)*Speed*Time.deltaTime; if((transform.position - wayPoint).magnitude < 3) { // when the distance between us and the target is less than 3 // create a new way point target Wander();
// don't need this
//transform.LookAt(wayPoint);
//transform.position += transform.TransformDirection(Vector3.forward)*Speed*Time.deltaTime;
}
}
function Wander() { // does nothing except pick a new destination to go to wayPoint= Random.insideUnitSphere *47; wayPoint.y = 1; // don't need to change direction every frame seeing as you walk in a straight line only transform.LookAt(wayPoint); Debug.Log(wayPoint + " and " + (transform.position - wayPoint).magnitude); }
Thank you spinaljack, I am still having some difficulties so I responded in the form of an answer so I could post my new code.
Answer by Alpine Flame · Dec 21, 2012 at 09:46 PM
Here's an update to this, I was noticing it always defaulted to 0,0,0 and then picked waypoints from there. This will cause it to wander aimlessly from it's origin.
var Speed= 20;
var wayPoint : Vector3;
var Range= 10;
function Start(){
//initialise the target way point
Wander();
}
function Update()
{
// this is called every frame
// do move code here
transform.position += transform.TransformDirection(Vector3.forward)*Speed*Time.deltaTime;
if((transform.position - wayPoint).magnitude < 3)
{
// when the distance between us and the target is less than 3
// create a new way point target
Wander();
}
}
function Wander()
{
// does nothing except pick a new destination to go to
wayPoint= Vector3(Random.Range(transform.position.x - Range, transform.position.x + Range), 1, Random.Range(transform.position.z - Range, transform.position.z + Range));
wayPoint.y = 1;
// don't need to change direction every frame seeing as you walk in a straight line only
transform.LookAt(wayPoint);
Debug.Log(wayPoint + " and " + (transform.position - wayPoint).magnitude);
}
$$anonymous$$or word of caution here, if using navmesh and you set the destination inside your sphere to be in a navobstacle, you'll need to detect that and select a new position. This is one of the benefits of using fixed waypoints and wandering between them with a* or navmesh. Simply get the waypoints inside of your sphere and randomly navigate to one of them.
Answer by Panamamigo · Jul 22, 2010 at 01:48 AM
var Speed= 10; var wayPoint : Vector3;
function Wander() { wayPoint= Random.insideUnitSphere *47; wayPoint.y = 1; Debug.Log(wayPoint + " and " + (transform.position - wayPoint).magnitude); }
function Update() { if((transform.position - wayPoint).magnitude < 3) { Wander(); transform.LookAt(wayPoint); transform.position += transform.TransformDirection(Vector3.forward)*Speed*Time.deltaTime; } }
The reason it's moving slowly is because you're using force and the objects is either very heavy or has high friction. Change it to transform.position += transform.TransformDirection(Vector3.forward)*speed*Time.deltaTime
also you've put your actual movement code inside a function and not the update, it'll only move one every time the function is called ins$$anonymous$$d of every frame like it should
I tried that, but it still isn't working with the transform.position += transform.TransformDirection...etc. When I use that it does not move at all. When I use other methods like transform.Translate or something it only moves a fraction of the way. What could be wrong? Thank you so much for all your help spinaljack it's really helping me out! I edited my question with the code.
Answer by pistacheeter · Jul 04, 2017 at 11:22 AM
This is for anyone who wants the c# version
using UnityEngine;
using System.Collections;
public class Wander : MonoBehaviour
{
[SerializeField]
float Speed = 20;
Vector3 wayPoint;
[SerializeField]
int Range = 10;
void Start()
{
//initialise the target way point
wander();
}
void Update()
{
// this is called every frame
// do move code here
transform.position += transform.TransformDirection(Vector3.forward) * Speed * Time.deltaTime;
if ((transform.position - wayPoint).magnitude < 3)
{
// when the distance between us and the target is less than 3
// create a new way point target
wander();
}
}
void wander()
{
// does nothing except pick a new destination to go to
wayPoint = new Vector3(Random.Range(transform.position.x - Range, transform.position.x + Range), 1, Random.Range(transform.position.z - Range, transform.position.z + Range));
wayPoint.y = 1;
// don't need to change direction every frame seeing as you walk in a straight line only
transform.LookAt(wayPoint);
Debug.Log(wayPoint + " and " + (transform.position - wayPoint).magnitude);
}
}
Answer by IMemeManI · Jan 15, 2018 at 04:54 PM
Or instead of all that from above you could simply do this?
Vector3 pos = Random.insideUnitSphere * wanderRadius;
nma.SetDestination(pos);
With a bit of adjustment you can make it filter out returned values that aren't on the NavMesh. I use this because Sampling a position on the NM returns either 0,0,0 or Infinite,Infinite,Infinite for me.
That's if you decided to switch to Nav$$anonymous$$esh ^
Your answer
Follow this Question
Related Questions
AI to make an object wander around and avoid obstacles? 5 Answers
A node in a childnode? 1 Answer
Wandering Code Not Working When Player Hides 1 Answer
AI help please :) 2 Answers
Clearing a destination... 1 Answer