NavmeshAgent player not parallel to slope of hill when moving over hill

旧街凉风 提交于 2019-11-29 09:01:44

I am not sure if NavmeshAgent is supposed to do that for you. This looks like something you're supposed to do manually.

You can correct the rotation of the character to match the slope by performing a raycast downwards and obtaining the normal of the hit point. After obtaining the normal of the hit point, you can then calculate the new rotation with that normal hit point. There are many ways to do that calculation but using Quaternion.FromToRotation and lerping the rotation with Quaternion.Lerp seems to work best.

Finally, make sure to the raycast is only done to Objects you considered as a "Hill" or "Ground". You can do this with the bitwise operation on the layer the "Hill" or "Ground" objects are placed on. The example below assumes that the Objects you consider as "Hill" or "Ground" are on a layer called "Hill".

//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);

    }

}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!