我遇到了这个问题:我需要敌人朝目标位置移动,但我的问题是我在Update函数中写了这个,所以“foreach”语句只在一帧中完成。此外,从未显示“到达航点”句子。我怎么解决这个问题?
以下是代码:`public class WayPointMovement:MonoBehaviour {
public EnemyDataSpawn enemy;
private Vector3 lastPos;
void Start ()
{
lastPos = gameObject.transform.position;
}
void Update ()
{
gameObject.transform.LookAt (LevelManager.current.playerObject.transform);
//WaypointData is a scriptable object that contains the definition of "x" and "z" coordinates.
foreach (WaypointData waypoints in enemy.enemy.waypoint) {
Debug.Log (waypoints.x);
gameObject.transform.position = Vector3.MoveTowards (gameObject.transform.position, new Vector3 (lastPos.x + waypoints.x, 0f, lastPos.z + waypoints.z), Time.deltaTime * enemy.enemy.easySpeedMovement);
if (gameObject.transform.position.x == lastPos.x + waypoints.x && gameObject.transform.position.z == lastPos.z + waypoints.z) {
Debug.Log("waypoint reached");
lastPos = gameObject.transform.position;
}
}
}
}`
答案 0 :(得分:1)
您需要重做Update
,这样才能完成一个框架的工作。这意味着你必须记住a)你走向哪个方向点,以及b)你走了多远。当你真正到达它时,你只能移动到下一个航路点。
有两种方法可以通过航点跟踪进度:
<德尔> 1。您可以在到达时简单地删除航点。然后,您尝试前往的航点始终是列表中的第一个。
<德尔> 2。如果你想保留航点,那么你需要一个额外的变量来跟踪你正在当前移动的哪个航路点。这可能类似于数组或列表的索引,也可能是每次完成航点时都调用IEnumerator<WaypointData>
的枚举器(MoveNext
)。
您已经指出(在此回答的评论中)您不想在到达时删除航点。允许您随意添加新航点的最灵活的安排是使用索引变量:
int waypointIndex;
void Start()
{
waypointIndex = 0;
}
void Update()
{
if (waypointIndex < waypoints.Count)
{
update position;
if (reached waypoint)
{
waypointIndex++;
}
}
}
然后,在你的Update
方法中,不是编写循环,而是更新游戏对象的位置一次,检查它是否只到达航点一次,如果有,请继续返回前的下一个航点。如果需要多次移动才能到达航点,您可以允许多次调用Update
;每个Update
只是运动的一个步骤。
您需要更好的逻辑来确定何时到达航路点。正如其他评论者指出的那样,使用浮点值,只需检查它们是否完全相同就不太可能有效。相反,您可以检查到航点的距离是否小于Time.deltaTime * enemy.enemy.easySpeedMovement
,如果是,则不是使用Vector3.MoveTowards
,而是将位置精确地设置为航点,并将该步骤视为具有到了航点。
这里是粗略的逻辑(伪代码)(但不像我第一次编写时那样伪代码):
Vector3 lastPos;
int waypointIndex;
void Start()
{
lastPos = gameObject.transform.position;
waypointIndex = 0;
}
void Update()
{
if (waypointIndex < waypoints.Count)
{
waypointPosition = new Vector3 (lastPos.x + waypoints.x, 0f, lastPos.z + waypoints.z);
if (Vector3.Distance(gameObject.transform.position, waypointPosition) > length of one step)
{
gameObject.transform.position = Vector3.MoveToward(gameObject.transform.position, waypointPosition);
}
else
{
gameObject.transform.position = waypointPosition;
log("Waypoint reached");
waypointIndex++;
}
}
}
答案 1 :(得分:1)
使用Vector3.sqrMagnitude比较亲密度。您可以定义&#34;关闭&#34;足够接近。我将在此示例中将航点用作Vector3
。您可以随意确定航路点Vector3
。
// define this globally
public float closeEnough = 5f;
// Within your compare method
if((gameObject.transform.position - waypoint).sqrMagnitude < closeEnough)
{
Debug.Log("waypoint reached");
}
注意:Vector3 - Vector3
的结果是另一个Vector3
。