NavmeshAgent玩家在山上移动时不平行于山坡

时间:2018-11-02 11:20:02

标签: c# unity3d navmesh

NavmeshAgent玩家在山丘上移动时不能与山坡平行。在平面上其运行平稳。

See Video

在navMesh和播放器的 Image 属性下方 https://ibb.co/fijmoV

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class SampleAgentScript : MonoBehaviour {
public Transform  target ;
NavMeshAgent agent;
//  private static bool start1=false , start2=false, start3;
// Use this for initialization

void Start()
{
    agent = GetComponent<NavMeshAgent>();
}



void Update()
{

    //if white button click moves to targer-1

    agent.SetDestination(target.position);

}

}

1 个答案:

答案 0 :(得分:3)

我不确定NavmeshAgent是否适合您。这看起来像您应该手动执行的操作。

您可以通过向下进行射线投射并获得击中点的法线来校正角色的旋转以匹配坡度。在获得了击中点的法线之后,您可以使用该击中点计算新的旋转。有许多方法可以执行此计算,但是使用Quaternion.FromToRotation并用Quaternion.Lerp限制旋转似乎效果最好。

最后,请确保仅对您视为“山丘”或“地面”的对象进行光线投射。您可以通过在“希尔”或“地面”对象所在的图层上按位操作来执行此操作。下面的示例假定您认为“山丘”或“地面”的对象在名为“山丘”的图层上。

//Reference of the moving GameObject that will be corrected
public GameObject movingObject;

//Offset postion from where the raycast is cast from
public Vector3 originOffset;
public float maxRayDist = 100f;

//The speed to apply the corrected slope angle
public float slopeRotChangeSpeed = 10f;

void Update()
{
    //Get the object's position
    Transform objTrans = movingObject.transform;
    Vector3 origin = objTrans.position;

    //Only register raycast consided as Hill(Can be any layer name)
    int hillLayerIndex = LayerMask.NameToLayer("Hill");
    //Calculate layermask to Raycast to. 
    int layerMask = (1 << hillLayerIndex);


    RaycastHit slopeHit;

    //Perform raycast from the object's position downwards
    if (Physics.Raycast(origin + originOffset, Vector3.down, out slopeHit, maxRayDist, layerMask))
    {
        //Drawline to show the hit point
        Debug.DrawLine(origin + originOffset, slopeHit.point, Color.red);

        //Get slope angle from the raycast hit normal then calcuate new pos of the object
        Quaternion newRot = Quaternion.FromToRotation(objTrans.up, slopeHit.normal)
            * objTrans.rotation;

        //Apply the rotation 
        objTrans.rotation = Quaternion.Lerp(objTrans.rotation, newRot,
            Time.deltaTime * slopeRotChangeSpeed);

    }

}