我已经设置了Unity导航网格(四个平面)、导航代理(球体),并设置了自动和手动脱离网格链接。它现在应该在网格之间跳跃。它确实在网格之间跳跃,但它是在直线上跳跃的。
换句话说,当代理到达边缘时,它并没有真正跳起来(就像绘制了脱离网格的链接一样),而是直线移动,但速度会更快。我试着把一个平面移得比其他平面高,但球体仍然在直线上跳跃。
应该是这样吗?是否可以设置导航以跳过某个曲线?或者我应该试着自己去实现它?
我遇到了这个问题,不得不深入研究Unity样本。我只是希望通过提取重要的部分来让人们更容易。
要在导航网格链接上应用您自己的动画/转换,您需要告诉Unity您将处理所有脱离网格链接遍历,然后添加定期检查代理是否在脱离网格链接上的代码。最后,当过渡完成时,你需要告诉Unity你已经移动了代理,并恢复正常的导航网格行为。
处理链接逻辑的方式取决于您。你可以沿着一条直线走,有一个旋转的虫洞,不管怎样。对于jump,unity使用动画进度作为lerp参数遍历链接,效果非常好。(如果你在做循环或更复杂的动画,这就不太好用了)
重要的单位位是:
_navAgent.autoTraverseOffMeshLink = false; //in Start()
_navAgent.currentOffMeshLinkData; //the link data - this contains start and end points, etc
_navAgent.CompleteOffMeshLink(); //Tell unity we have traversed the link (do this when you've moved the transform to the end point)
_navAgent.Resume(); //Resume normal navmesh behaviour
现在是一个简单的跳转示例。。。
using UnityEngine;
[RequireComponent(typeof(NavMeshAgent))]
public class NavMeshAnimator : MonoBehaviour
{
private NavMeshAgent _navAgent;
private bool _traversingLink;
private OffMeshLinkData _currLink;
void Start()
{
// Cache the nav agent and tell unity we will handle link traversal
_navAgent = GetComponent<NavMeshAgent>();
_navAgent.autoTraverseOffMeshLink = false;
}
void Update()
{
//don't do anything if the navagent is disabled
if (!_navAgent.enabled) return;
if (_navAgent.isOnOffMeshLink)
{
if (!_traversingLink)
{
//This is done only once. The animation's progress will determine link traversal.
animation.CrossFade("Jump", 0.1f, PlayMode.StopAll);
//cache current link
_currLink = _navAgent.currentOffMeshLinkData;
//start traversing
_traversingLink = true;
}
//lerp from link start to link end in time to animation
var tlerp = animation["Jump"].normalizedTime;
//straight line from startlink to endlink
var newPos = Vector3.Lerp(_currLink.startPos, _currLink.endPos, tlerp);
//add the 'hop'
newPos.y += 2f * Mathf.Sin(Mathf.PI * tlerp);
//Update transform position
transform.position = newPos;
// when the animation is stopped, we've reached the other side. Don't use looping animations with this control setup
if (!animation.isPlaying)
{
//make sure the player is right on the end link
transform.position = _currLink.endPos;
//internal logic reset
_traversingLink = false;
//Tell unity we have traversed the link
_navAgent.CompleteOffMeshLink();
//Resume normal navmesh behaviour
_navAgent.Resume();
}
}
else
{
//...update walk/idle animations appropriately ...etc
建议通过动画解决您的问题。只需为对象创建一个Jump
动画,然后在正确的时间播放即可。该位置是相对的,因此如果在动画中增加Y位置,则对象看起来像是在跳跃。
这也是Unity样本的工作方式,士兵们四处奔跑。
不确定您使用的是哪种版本的统一,但您也可以尝试一下,我知道它在4:中运行得很好
string linkType = GetComponent<NavMeshAgent>().currentOffMeshLinkData.linkType.ToString();
if(linkType == "LinkTypeJumpAcross"){
Debug.Log ("Yeah im in the jump already ;)");
}
也只是一些额外的bumf为你,它最好使用代理并遵循一个navAgent游戏对象:
类似于:
AIMan=this.transform.position;AI_Proxy.transform.position=AIMan;
并且一定要使用:
AI_Poxy.animation["ProxyJump"].blendMode=AnimationBlendMode.Anditive;
如果您正在使用内置的统一动画!
K、 这是我本周的善举。
修复update()中的位置
if (agent.isOnOffMeshLink)
{
transform.position = new Vector3(transform.position.x, 0f, transform.position.z);
}