unity3d 检查刚体是否固定?

c6ubokkw  于 2023-01-31  发布在  其他
关注(0)|答案(5)|浏览(150)

我有一个游戏对象与刚体,网格碰撞器,蒙皮网格渲染器,和下面的脚本。
我试图检查它是否接地,但控制台不断吐出“未接地!”当它是,所以很明显的东西是错误的。有人能请帮助?

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!");
        }
    }
}
kgqe7b3p

kgqe7b3p1#

检查刚体是否固定的另一个选项是使用OnTriggerStay函数。

void OnTriggerStay(Collider other)
    {
        if (other.Transform.Tag == "Ground")
        {
            IsGrounded = true;
            Debug.Log("Grounded");
        }
        else
        {
            IsGrounded = false;
            Debug.Log("Not Grounded!");
        }
    }
wj8zmpe1

wj8zmpe12#

我用一个简单的场景检查了你的代码,这个场景有一个平面和一个立方体,它工作正常。
只有当对象明显地“漂浮”在周围或对象的一半身体在平面之外时,它才会产生“不固定”。
检查这些东西drawing的射线,这应该会给予你更多的信息是什么出了问题,你的网格。
此外,如果问题是游戏如何感知蒙皮网格的高度,您也可以使用SkinnedMeshRenderer.localBounds,它返回对象的AABB。

7rfyedvj

7rfyedvj3#

有一种比碰撞检查和射线更好的方法来检查刚体是否固定。但首先,为什么碰撞检查不是一个好主意:如果你的关卡是一个单一的模型,墙壁也会被标记为“地面”标签,并且击中墙壁会返回真,这是你不希望的。射线可以使用,但这是太多的数学你不需要浪费时间。
不要使用新的对象和方法,只需检查位置是否发生了变化:

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;
}

从这里开始,由您决定要添加什么逻辑。

e5njpo68

e5njpo684#

使最接近底部的接触点。检查接触法线是否在范围内。

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的答案后,我得出了这个答案。

5uzkadbs

5uzkadbs5#

private void Jump()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        if (transform.position.y == 0f)
        {
            rb.AddRelativeForce(Vector3.up * jumpForce);
        }
    }
}

我用这种方法来跳跃,只在y的位置为0时,才加上刚体的相对力。

相关问题