我已更改标题以反映添加的澄清信息。
我正在关注 [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 OnGroundClick
fxn 并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-3
我Debug.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;
}
}