2

我已更改标题以反映添加的澄清信息。

我正在关注 [Unity 教程][1],当需要测试播放器点击控件时,Unity 给了我一个错误:

“SetDestination”只能在已放置在 NavMesh 上的活动代理上调用。

据我所知,我的代理处于活动状态并且在 navMesh 上,所以这有点令人困惑。我已经尝试重新烘焙 navMesh 并重新定位代理,但两者都不起作用。

到目前为止,我发现的所有问题都相当于提问者根本没有导航网格,所以......是的......不是很有帮助。任何有关如何解决此问题的建议都将不胜感激。

编辑: 我刚刚Debug.Log(agent.isOnNavMesh);在我的代码中添加了一个快速 & 低 & 看它评估为true. 偷看混乱。

private void Start()
    {
        Debug.Log(agent.isOnNavMesh);       //Evaluates *true*
        agent.updateRotation = false;

        inputHoldWait = new WaitForSeconds(inputHoldDelay);

        destinationPosition = transform.position;
    }

EDIT-2 将相同的内容Debug.Log(agent.isOnNavMesh);放入我的public void OnGroundClickfxn 并false在点击后评估。开始好奇的困惑。

这由 Unity 事件系统调用:

public void OnGroundClick(BaseEventData data)
{
    Debug.Log(agent.isOnNavMesh);       //Evaluates *FALSE*
    PointerEventData pData = (PointerEventData)data;
    NavMeshHit hit;

        //Click World Position, hit info, sample distance, navMesh areas to use
    if (NavMesh.SamplePosition(pData.pointerCurrentRaycast.worldPosition, out hit, navMeshSampleDistance, NavMesh.AllAreas))
    {
        destinationPosition = hit.position;
    }
    else
    {
        destinationPosition = pData.pointerCurrentRaycast.worldPosition;
    }

    //give the agent it's destination
    agent.SetDestination(destinationPosition);
    agent.isStopped = false;
}

EDIT-3Debug.Log(agent.isOnNavMesh);输入到private void Update(),它评估为true并继续这样做,即使在 Click 调用之后也是如此public void OnGroundClick

在开始时禁用然后启用代理OnGroundClick不会影响情况

尽管我仍然不知所措,但我至少离解决方案更近了,而且还有比“这不起作用,请帮助!”更多的信息。现在。

这是完整上下文中的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.AI;

public class PlayerMovement : MonoBehaviour
{
    public Animator animator;                               //Reference to animator
    public NavMeshAgent agent;                              //Reference to NavMeshAgent
    public float inputHoldDelay = 0.5f;                     //Delay player ability to control character while interacting with interactable object
    public float turnSpeedThreshold = 0.5f;                 //minimum speed before character will turn
    public float speedDampTime = 0.1f;                      //Character rate acceleration
    public float slowingSpeed = 0.175f;                     //Character rate of neg accel
    public float turnSmoothing = 15;                        //Character rotational speed


    private WaitForSeconds inputHoldWait;                   //Coroutine Wait timer to delay player input while interacting with interactable object
    private Vector3 destinationPosition;                    //Player designated destination for the agent to pursue


    private const float stopDistanceProportion = 0.1f;
    private const float navMeshSampleDistance = 4f;


    private readonly int hashSpeedParam = Animator.StringToHash("Speed");


    private void Start()
    {
        Debug.Log(agent.gameObject.name);   //Is the "Player" object
        Debug.Log(agent.isOnNavMesh);       //Evaluates *true*
        agent.updateRotation = false;

        inputHoldWait = new WaitForSeconds(inputHoldDelay);

        destinationPosition = transform.position;
    }


    private void OnAnimatorMove()
    {
        //Velocity = Distance over Time, where Distance = change in position between frames & Time = time between frames
        agent.velocity = animator.deltaPosition / Time.deltaTime;
    }


    private void Update()
    {
        Debug.Log(agent.isOnNavMesh);       //Evaluates *true*
        //If path pending, do nothing
        if (agent.pathPending)
            return;

        float speed = agent.desiredVelocity.magnitude;

        if (agent.remainingDistance <= agent.stoppingDistance * stopDistanceProportion)
        {
            Stopping(out speed);
        }
        else if (agent.remainingDistance <= agent.stoppingDistance)
        {
            Slowing(agent.remainingDistance, out speed);
        }
        else if(speed > turnSpeedThreshold)
        {
            Moving();
        }

        animator.SetFloat(hashSpeedParam, speed, speedDampTime, Time.deltaTime);
    }


    private void Stopping(out float speed)
    {
        agent.isStopped = true;
        transform.position = destinationPosition;
        speed = 0.0f;
    }


    private void Slowing(float distanceToDestination, out float speed)
    {
        agent.isStopped = true;
        transform.position = Vector3.MoveTowards(transform.position, destinationPosition, slowingSpeed * Time.deltaTime);

        float proportionalDistance = 1f - distanceToDestination / agent.stoppingDistance;
        speed = Mathf.Lerp(slowingSpeed, 0, proportionalDistance);
    }


    private void Moving()
    {
        Quaternion targetRotation = Quaternion.LookRotation(agent.desiredVelocity);
        transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, turnSmoothing * Time.deltaTime);
    }


    public void OnGroundClick(BaseEventData data)
    {
        agent.enabled = false;              //Disabling then enabling the agent...
        agent.enabled = true;               //does not change anything.

        Debug.Log(agent.gameObject.name);   //Is the "Player" object
        Debug.Log(agent.isOnNavMesh);       //Evaluates *FALSE*

        PointerEventData pData = (PointerEventData)data;
        NavMeshHit hit;

            //Click World Position, hit info, sample distance, navMesh areas to use
        if (NavMesh.SamplePosition(pData.pointerCurrentRaycast.worldPosition, out hit, navMeshSampleDistance, NavMesh.AllAreas))
        {
            destinationPosition = hit.position;
        }
        else
        {
            destinationPosition = pData.pointerCurrentRaycast.worldPosition;
        }

        //give the agent it's destination
        agent.SetDestination(destinationPosition);
        agent.isStopped = false;
    }
}
4

1 回答 1

0

您有两个PlayerMovement引用代理的两个不同实例的组件实例!

一个实例是agent.isOnNavMeshis并且在and中true正常工作。另一个实例指的是不同的where is但这是被调用的那个。StartUpdateagentagent.isOnNavMeshfalseOnGroundclick

我们可以判断,因为在vs.GetInstanceID()中返回不同的值。UpdateOnGroundClick

这里的解决方案是确保OnGroundClick在事件系统中注册的那个是正确实例中的那个PlayerMovement

于 2019-06-13T17:38:14.127 回答