dimanche 1 mars 2015

Can't make my Enemy to randomly move in a range. Unity3D

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);
}
}


NOTE: The map is supposed to be flat but It would be great if the code worked for a map with variable heigth. Im moving the char with a Character Controller is it the correct approach?





Aucun commentaire:

Enregistrer un commentaire