【发布时间】:2015-03-01 14:12:55
【问题描述】:
嗨:我正在制作一个 FPS 与一些 3D 生存混合。我有一个代表我的敌人的动画模型。如果我在范围内,我可以让他向我移动。如果他离得足够近,他就会停止移动(和动画)。现在我试图实现一个流浪的行为。
我的想法是这样的:敌人从起始位置开始。他检查玩家是否在范围内,如果为真,则 FollowPlayer(),如果为假,则为 MoveAround(),这意味着他在其实际位置的某个范围内计算一个随机位置,Slerp 到该位置,然后移动到该随机位置。到达随机位置后,他应该等待 X 秒,直到下一个动作。我拥有的 MoveAround() 方法是协程,但我无法使其工作。这是脚本:
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 ("Player Pos: " + playerPos);
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("waiting the first 2 seconds");
}
Debug.Log ("arrived at destination");
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);
}
}
注意:地图应该是平坦的,但如果代码适用于具有可变高度的地图,那就太好了。 我用字符控制器移动字符是正确的方法吗?
【问题讨论】:
-
我可以看看你的调试日志吗?为 playerPos 添加一个
-
当然:当我点击播放时,敌人设置在 (50,0,50)。然后这是第一个控制台日志: ·Player Pos: (0.6, 0.0, 31.7) ·Random Pos: (50.5, 0.0, 48.0) ·Look Dir: (0.5, 0.0, -2.0) ·Move Dir: (0.0, 0.0 , 0.0)·移动敌人·移动敌人
标签: c# random unity3d artificial-intelligence