首页 > 解决方案 > Unity:raycast groundcheck 2d 不起作用

问题描述

所以我想检查一下我的性格下是否有底线

这是代码

public class move2d : MonoBehaviour
{
    public float moveSpeed = 7f;
    public float distanceGround;
    public bool isGrounded = false;
    // Start is called before the first frame update
    void Start()
    {
        distanceGround = GetComponent<Collider2D>().bounds.extents.y;
    }

    // Update is called once per frame
    void Update()
    {
        if (Physics2D.Raycast(transform.position, -Vector2.up, distanceGround + 0.1f))
        {
             
        }
        else
        {
            isGrounded = true;
            Jump();
        }
        Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0f, 0f);
        transform.position += movement * Time.deltaTime * moveSpeed;
    }

    void Jump()
    {
        if (Input.GetButtonDown("Jump")  )
        {
            gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, 8f), ForceMode2D.Impulse);
        }
    }

    
}

但它不起作用,我不明白为什么即使我的角色在地面上,它也不会进入 else 语句。

标签: c#unity3dgame-physics

解决方案


在处理刚体时,您不应该使用transform.positionnot 来获取和设置值。而是用于Rigidbody2D.position获取和设置。Rigidbody2D.MovePositionFixedUpdate

也不应该反过来吗?如果光线投射击中某些东西,您很可能会被接地..如果没有,则不是?

// Already reference these via the Inspector
[SerializeField] private RigidBody2D rigidBody2D;
[SerializeField] private Collider2D _collider2D;

public float moveSpeed = 7f;
public float distanceGround;

private Vector2 movement;
private bool jumped;

private void Awake ()
{
    // Alternately get it once on runtime
    if(! rigidBody2D) rigidBody2D = GetComponent<RigidBody2D>();
    if(!_collider2D) _collider2D = GetComponent<Collider2D>();
}

private void Start()
{
    // Micro performance improvement by calculating this only once ;)
    distanceGround = _collider2D.bounds.extents.y + 0.1f;
}

// Get user Input every frame
private void Update()
{
    // Directly check for the button
    if (Input.GetButtonDown("Jump"))
    {
        // if button presed set the jump flag
        jumped = true;
    }

    // store user input
    movement = Vector3.right * Input.GetAxis("Horizontal");
}

// Apply physics in the physics update
private void FixedUpdate()
{
    // If jump flag is set
    if(jumped)
    {
        // You are grounded when you hit something, not the other way round
        if (Physics2D.Raycast(rigidBody2D.position, Vector2.down, distanceGround))
        {
            rigidbody2D.AddForce(Vector2.up * 8f, ForceMode2D.Impulse);
        }

        // reset the flag
        jumped = false;
    }

    // apply the normal movement without breaking the physics
    rigidBody2D.MovePosition(rigidBody2D.position + movement * Time.deltaTime * moveSpeed);
}

推荐阅读