OnTriggerEnter2D()似乎无法统一工作

时间:2019-09-13 05:24:19

标签: c# unity3d

我正在开发一个平台游戏,其中一个球应该能够左右移动并跳跃。我可以使角色成功跳跃或移动,但是当我尝试检查它是否在地面上时,通过使用触发器对撞机2D创建一个作为该角色的子元素的元素,并使用一个应该玩家接触地面时为true,否则为false,只是没有激活。

以下是主要运动脚本的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Grounded : MonoBehaviour
{
    GameObject Player;

    // Start is called before the first frame update
    void Start()
    {
        Player = gameObject.transform.parent.gameObject;
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (GetComponent<Collider2D>().tag == "Ground")
        {
            Player.GetComponent<Move2D>().isGrounded = true;
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (GetComponent<Collider2D>().tag == "Ground")
        {
            Player.GetComponent<Move2D>().isGrounded = true;
        }
    }
}

这是 Grounded 脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move2D : MonoBehaviour
{
    public float moveSpeed = 5f;
    public bool isGrounded = false;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        Jump();
        Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0f, 0f);
        transform.position += movement * Time.deltaTime * moveSpeed;
    }

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

任何帮助或信息都非常感谢。

2 个答案:

答案 0 :(得分:1)

您能检查一下球和地面是否都具有刚体?触发触发器是必需的。

*注意:仅当其中一个碰撞器还附有刚体时才发送触发事件。 *

您还可以更改代码

private void OnTriggerEnter2D(Collider2D collision)
{
    if (GetComponent<Collider2D>().tag == "Ground")
    {
        Player.GetComponent<Move2D>().isGrounded = true;
    }
}


private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.tag == "Ground")
    {
        Player.GetComponent<Move2D>().isGrounded = true;
    }
}

我也建议您使用“图层”而不是标签

答案 1 :(得分:1)

GetComponent<Collider2D>().tag == "Ground"

您正在检查此GameObject(玩家的孩子)对撞机本身的tag

您可能宁愿检查与之碰撞的事物的tag

也要避免重复GetComponent调用..而不是只执行一次。

(感谢@Jichael)您也应该使用CompareTag而不是tag == "XY"。它是more efficient,实际上还检查给定的比较字符串是否作为标记存在。如果没有,则在使用==时会抛出错误,只是返回false,这使得很难找到evtl。错字。

// Would be better even to already reference this via Inspector
[SerializeField] private Move2D Player;

private void Awake()
{
    if(!Player) Player = GetComponentInParent<Move2D>();
}

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.CompareTag("Ground"))
    {
        Player.isGrounded = true;
    }
}

private void OnTriggerExit2D(Collider2D collision)
{
    if (collision.CompareTag("Ground"))
    {
        Player.isGrounded = true;
    }
}

Move2D

中也是如此
[SerializeField] private Rigidbody2D rigidbody;

private void Awake()
{
    if(!rigidbody) rigidbody = GetComppnent<Rigidbody2D>();
}

void Jump()
{
    // This is very small but it is slightly cheaper to check the 
    // isGrounded value so this order is minimal faster if isGrounded is false
    if (isGrounded && Input.GetButtonDown("Jump"))
    {
        rigidbody.AddForce(new Vector3(0f, 5f), ForceMode2D.Impulse);
    }
}

还请注意:每当涉及到刚体时,您都不应通过Transform组件控制位置,而应使用Rigidbody2D.MovePosition来保持物理状态不变!

但这必须在FixedUpdate中完成,这样您的代码才能变成类似

private Vector3 movement;

void Update()
{
    Jump();
    movement = new Vector3(Input.GetAxis("Horizontal"), 0f, 0f);
}

private void FixedUpdate ()
{
    rigidbody.MovePosition(rigidbody.position += movement * Time.deltaTime * moveSpeed);
}

void Jump()
{
    if (Input.GetButtonDown("Jump") && isGrounded)
    {
        rigidbody.AddForce(new Vector3(0f, 5f), ForceMode2D.Impulse);
    }
}

这两个对象是否都需要刚体或仅玩家依赖地面对象(afaik):

  • 地面物体是静态的→一个(玩家)刚体就足够了
  • 地面对象移动→都需要一个刚体(地面,例如运动学对象)
相关问题