首页 > 解决方案 > Vector3.MoveTowards 不工作。它不会移动或显示任何错误

问题描述

当使用 Vector3.MoveTowards 时,它不会对其中任何一个做任何事情,因为一个无法运行导致另一个无法运行。

这是我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class PlaneAI : MonoBehaviour
{
    public Transform[] runwayPoints;
    public Transform[] startTakeoffPoints;
    public Transform[] takeoffPoints;
    public NavMeshAgent navMeshAgent;
    public bool takeoff = false;
    bool departing = false;
    bool moving = false;
    int selectedRunway;
    public IEnumerator Depart()
    {
        navMeshAgent.SetDestination(runwayPoints[selectedRunway = Random.Range(0, runwayPoints.Length)].position);
        yield return new WaitForSeconds(3f);
        departing = true;
    }
    public void Update()
    {
        if (Input.GetKeyDown(KeyCode.P))
        {
            StartCoroutine(Depart());
        }
        GetComponent<LineRenderer>().SetPosition(0, new Vector3(transform.position.x, 1, transform.position.z));
        GetComponent<LineRenderer>().SetPosition(1, navMeshAgent.destination);
        if (navMeshAgent.pathStatus == NavMeshPathStatus.PathComplete && departing && navMeshAgent.remainingDistance == 0)
        {
            Takeoff();
        }
        if (moving && Vector3.Distance(transform.position, startTakeoffPoints[selectedRunway].position) <= 0.001f)
        {
            transform.position = Vector3.MoveTowards(transform.position, takeoffPoints[selectedRunway].position, 3); // this one does not work it should be after the other one
            transform.LookAt(takeoffPoints[selectedRunway]);
            takeoff = false;
        }
    }
    public void Takeoff()
    {
        navMeshAgent.enabled = false;
        GetComponent<Collider>().enabled = false;
        transform.LookAt(new Vector3(takeoffPoints[selectedRunway].position.x, 0, takeoffPoints[selectedRunway].position.z));
        MoveTakeoff();
        departing = false;
    }
    public void MoveTakeoff()
    {
        transform.position = Vector3.MoveTowards(transform.position, startTakeoffPoints[selectedRunway].position, 2); // this one does not work
        moving = true;
        takeoff = false;
    }
}

没有脚本错误,它只是不起作用。

我认为不相关的唯一错误是:

“无效的 worldAABB。对象太大或离原点太远。”

“无效的 localAABB。对象转换已损坏。”

“表达式上的断言失败:'IsFinite(d)' UnityEngine.GUIUtility:processEvent(Int32, IntPtr)”

“表达式上的断言失败:'IsFinite(outDistanceForSort)' UnityEngine.GUIUtility:processEvent(Int32, IntPtr)”

“表达式上的断言失败:'IsFinite(outDistanceAlongView)' UnityEngine.GUIUtility:processEvent(Int32, IntPtr)”

标签: c#unity3d

解决方案


您需要更好地将状态转换逻辑与状态活动逻辑分开。当状态转换发生在相同的块中时,您应该运行的代码与应该在状态处于活动状态的每一帧中运行的代码相同。

您可以处理此问题的一种方法是将您的状态转换为协程:

public class PlaneAI : MonoBehaviour
{
    public Transform[] runwayPoints;
    public Transform[] startTakeoffPoints;
    public Transform[] takeoffPoints;
    public NavMeshAgent navMeshAgent;
    public bool takeoff = false;
    bool departing = false;
    bool moving = false;
    int selectedRunway;

    LineRenderer lr;

    void Awake()
    { 
        lr = GetComponent<LineRenderer>();
    }

    IEnumerator Depart()
    {
        navMeshAgent.SetDestination(runwayPoints[selectedRunway = Random.Range(0, 
                runwayPoints.Length)].position);
        yield return new WaitForSeconds(3f);

        departing = true;
        while(departing)
        {           
            if (navMeshAgent.pathStatus == NavMeshPathStatus.PathComplete 
                    && navMeshAgent.remainingDistance == 0)
            {
                StartCoroutine(MoveTakeoff());
                yield break;
            }
            yield return null;
        }
    }

    IEnumerator MoveTakeOff()
    {
        departing = false;
        moving = true;

        navMeshAgent.enabled = false;
        GetComponent<Collider>().enabled = false;
        transform.LookAt(new Vector3(takeoffPoints[selectedRunway].position.x, 0,
                takeoffPoints[selectedRunway].position.z));

        while (moving)
        {
            if (Vector3.Distance(transform.position, 
                    startTakeoffPoints[selectedRunway].position) <= 0.001f)
            {                    
                StartCoroutine(TakeOff())
                yield return break;
            }

            transform.position = Vector3.MoveTowards(transform.position, 
                    startTakeoffPoints[selectedRunway].position, 2);

            yield return null;
        }
    }

    IEnumerator Takeoff()
    {
        moving = false;
        takeOff = true;

        transform.LookAt(takeoffPoints[selectedRunway]);

        while (takeOff)
        {
 
            if (Vector3.Distance(transform.position, 
                    startTakeoffPoints[selectedRunway].position) <= 0.001f)
            {
                takeoff = false;
                yield break;
            }

            transform.position = Vector3.MoveTowards(transform.position, 
                    takeoffPoints[selectedRunway].position, 3); 
            yield return null;
        }
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.P))
        {
            StopAllCoroutines();
            StartCoroutine(Depart());
        }

        lr.SetPosition(0, new Vector3(transform.position.x, 1, transform.position.z));
        lr.SetPosition(1, navMeshAgent.destination);

    }
}

理想情况下,状态应该是单个枚举器而不是几个布尔值,但这希望能说明我的意思。


推荐阅读