- Home /
Move Enemy randomly in a range. 3D
Hi: Im working on a FPS mixed with some survival in 3D. I have an animated model that represents my enemy. I can make him move towards me if I am in range. If he gets closer enough he stops moving(and animating). Now Im trying to achieve a Wandering behaviour.
My idea goes like this: The enemy starts in the start position. He checks if the player is in range, if true then FollowPlayer() if false then MoveAround(), this means that he calculate a random position in a certain range of his actual position, Slerp to it and then move to that random position. After reaching the random position he should wait X seconds until the next move . The MoveAround() method I have is a Coroutine but I cant make it work. Here is the script: using UnityEngine; using System.Collections;
public class EnemyAI : MonoBehaviour {
public float rotationSpeed;
public float moveSpeed;
public float maxSpeed;
public float minRange;
public float maxRange;
public float moveRange;
Animator anim;
CharacterController controller;
// Use this for initialization
void Awake (){
anim = GetComponent<Animator> ();
controller = GetComponent<CharacterController> ();
}
void Start () {
}
// Update is called once per frame
void FixedUpdate () {
FollowPlayer ();
StartCoroutine(MoveAround ());
}
void FollowPlayer(){
Vector3 playerPos = GameObject.Find ("Player").transform.position;
Vector3 lookDir = playerPos - transform.position;
Vector3 moveDir = lookDir;// * moveSpeed;
moveDir *= Time.fixedDeltaTime;
if((Vector3.Distance(transform.position, playerPos) <= maxRange) && (Vector3.Distance(transform.position, playerPos) > minRange) ){
Vector3 previous = transform.position;
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation (lookDir), rotationSpeed * Time.fixedDeltaTime);
controller.Move(moveDir);
float velocity = ((transform.position - previous).magnitude) / Time.fixedDeltaTime;
// Debug.Log("velocidad: " + velocity);
previous = transform.position;
anim.SetFloat ("speed", velocity);
}
if(Vector3.Distance(transform.position, playerPos) < minRange){
controller.Move(Vector3.zero);
Debug.LogWarning("hey");
anim.SetFloat("speed",controller.velocity.magnitude);
}
}
IEnumerator MoveAround(){
Vector3 playerPos = GameObject.Find ("Player").transform.position;
Vector3 randomPos = Random.onUnitSphere * moveRange;
randomPos = new Vector3 (randomPos.x + transform.position.x, transform.position.y, randomPos.z + transform.position.z);
Vector3 lookDir = randomPos - transform.position;
Vector3 moveDir = lookDir;
moveDir *= Time.fixedDeltaTime;
Debug.Log ("Random Pos: " + randomPos);
Debug.Log ("Look Dir: " + lookDir);
Debug.Log ("Move Dir: " + moveDir);
if(Vector3.Distance(transform.position, playerPos) > maxRange){
Debug.Log("Moving the enemy");
Vector3 previous = transform.position;
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation (lookDir), rotationSpeed * Time.fixedDeltaTime);
controller.Move(moveDir);
float velocity = ((transform.position - previous).magnitude) / Time.fixedDeltaTime;
// Debug.Log("velocidad: " + velocity);
previous = transform.position;
anim.SetFloat ("speed", velocity);
Debug.Log("Enemy moved");
yield return new WaitForSeconds(2f);
Debug.Log("esperando primeros 2 segundos");
}
Debug.Log ("he llegado al destino");
yield return new WaitForSeconds(2f);
Debug.Log ("COroutine final");
}
void OnDrawGizmosSelected(){
Gizmos.color = Color.green;
Gizmos.DrawWireSphere (transform.position, maxRange);
Gizmos.DrawWireSphere (transform.position, minRange);
}
}
// Update is called once per frame
void FixedUpdate () {
You should not be using FixedUpdate for this type of behaviour. Just stick to Update.
Is the Coroutine starting?
If it is, until which line of code the coroutine works?
Your answer
Follow this Question
Related Questions
Transform.translate change 1 Answer
Monster doesn't move 0 Answers
How To Make Enemy Move Around 0 Answers
Make AI walk around randomly until Player is Seen. (C#) 2 Answers