NavmeshAgent 播放器在越过山坡时不平行于山坡
NavmeshAgent player not parallel to slope of hill when moving over hill
NavmeshAgent 播放器在越过山坡时不平行 到山坡。在平面上它进展顺利。
低于 Image navMesh 和播放器的属性
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);
}
}
我不确定 NavmeshAgent
是否应该为您做那件事。这看起来像是您应该手动执行的操作。
您可以通过向下执行光线投射并获取命中点的法线来校正角色的旋转以匹配斜率。获得命中点的法线后,您可以使用该法线命中点计算新的旋转。有很多方法可以进行该计算,但使用 Quaternion.FromToRotation
并使用 Quaternion.Lerp
进行旋转似乎效果最好。
最后,确保只对您认为是 "Hill" 或 "Ground" 的对象进行光线投射。您可以在 "Hill" 或 "Ground" 对象所在的层上使用按位操作来执行此操作。下面的示例假设您认为 "Hill" 或 "Ground" 的对象位于名为 "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);
}
}
NavmeshAgent 播放器在越过山坡时不平行 到山坡。在平面上它进展顺利。
低于 Image navMesh 和播放器的属性 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);
}
}
我不确定 NavmeshAgent
是否应该为您做那件事。这看起来像是您应该手动执行的操作。
您可以通过向下执行光线投射并获取命中点的法线来校正角色的旋转以匹配斜率。获得命中点的法线后,您可以使用该法线命中点计算新的旋转。有很多方法可以进行该计算,但使用 Quaternion.FromToRotation
并使用 Quaternion.Lerp
进行旋转似乎效果最好。
最后,确保只对您认为是 "Hill" 或 "Ground" 的对象进行光线投射。您可以在 "Hill" 或 "Ground" 对象所在的层上使用按位操作来执行此操作。下面的示例假设您认为 "Hill" 或 "Ground" 的对象位于名为 "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);
}
}