[英]Checking if RigidBody is grounded?
我有一个带有 Rigidbody、Mesh Collider、Skinned Mesh Renderer 和以下脚本的 GameObject。
我正在尝试检查它是否已接地,但控制台在接地时不断吐出“未接地”。 很明显这里出了什么问题? 有人可以帮忙吗?
public class GroundCheck : MonoBehaviour
{
public float Height;
bool IsGrounded;
Ray ray;
MeshRenderer renda;
private void Start()
{
Height = renda.bounds.size.y;
}
void Update()
{
if (Physics.Raycast(transform.position, Vector3.down, Height))
{
IsGrounded = true;
Debug.Log("Grounded");
}
else
{
IsGrounded = false;
Debug.Log("Not Grounded!");
}
}
}
检查刚体是否接地的另一个选项是使用OnTriggerStay function。
void OnTriggerStay(Collider other)
{
if (other.Transform.Tag == "Ground")
{
IsGrounded = true;
Debug.Log("Grounded");
}
else
{
IsGrounded = false;
Debug.Log("Not Grounded!");
}
}
我已经用一个带有平面和立方体的简单场景检查了你的代码,它可以工作。
只有当它明显是“浮动”环绕或 object 的一半身体在飞机之外时,它才会生成 NotGrounded。
检查那些绘制射线的东西,这应该可以为您提供有关网格出了什么问题的更多信息。
此外,如果问题是游戏如何感知蒙皮网格的高度,您还可以使用SkinnedMeshRenderer.localBounds ,它返回 object 的 AABB。
有比碰撞检查和射线更好的方法来检查刚体是否接地。 但是首先,为什么碰撞检查不是一个好主意:如果您的关卡是单个 model,那么墙壁也将被标记为“Ground”标签并且撞到墙壁将返回 true,这是您不想要的。 可以使用光线,但你不需要浪费时间来处理太多的数学问题。
无需使用新的对象和方法,只需检查 position 是否发生变化:
private float lastYposition;
private bool grounded;
void Start() {
lastYposition = transform.position.y;
}
void Update() {
grounded = (lastYposition == transform.position.y); // Checks if Y has changed since last frame
lastYposition = transform.position.y;
}
从这里开始,您要添加什么逻辑取决于您。
private void Jump()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if (transform.position.y == 0f)
{
rb.AddRelativeForce(Vector3.up * jumpForce);
}
}
}
只有当 y 的 position 为 0 时,我才使用这种方法使用刚体的 addrelativeforce 进行跳跃。
获取最接近底部的接触点。 检查接触法线是否在范围内。
void OnCollisionStay(Collision collision)
{
var bottom = renderer.bounds.center;
bottom.y -= renderer.bounds.extents.y;
float minDist = float.PositiveInfinity;
float angle = 180f;
// Find closest point to bottom.
for (int i = 0; i < collision.contactCount; i++)
{
var contact = collision.GetContact(i);
var tempDist = Vector3.Distance(contact.point, bottom);
if(tempDist < minDist)
{
minDist = tempDist;
// Check how close the contact normal is to our up vector.
angle = Vector3.Angle(transform.up, contact.normal);
}
}
// Check if the angle is too steep.
if (angle <= 45f) IsGrounded = true;
else IsGrounded = false;
}
void OnCollisionExit(Collision collision)
{
IsGrounded = false;
}
阅读amitklein的回答后,我想出了这个答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.