【问题标题】:OnTriggerEnter2D is occurring too slowlyOnTriggerEnter2D 发生得太慢
【发布时间】:2019-11-14 10:56:59
【问题描述】:

我有一个 2d 角色,他可以使用下面的脚本发射一个带有rigidbody2d 的hookshot 射弹。当射弹与某个层(在 Physics2D 项目设置中选择)上的 tilemapcollider2d 碰撞时,它应该立即停止。但是,OnTriggerEnter2D 并不总是发生得足够快,导致弹丸在停止之前就被夹入瓷砖中。使用此设置的脚本基本上可以正常工作,而不是剪辑。

我知道 onCollisionEnter2D 和使用速度而不是 MoveTowards 可能是这里的解决方案,以在弹丸与该层的瓷砖碰撞时停止弹丸。不幸的是,我无法让它工作,我不确定为什么。我在 tilemapcollider2d 和弹丸刚体2d 上都取消选中“是触发器”,它直接通过,onCollisionEnter2D 事件从未被注册。

public class Hookshot : MonoBehaviour
{
private GameObject player;
private Vector2 playerPos;

private BoxCollider2D col;
private Rigidbody2D rbody;
public GameObject DustParticle;

private readonly float hookshotCastTime = 0.2f;
private readonly float hookshotReturnSpeed = 200f;
private readonly float hookshotDistanceBuffer = 0.2f;

private void Awake()
{
    col = GetComponent<BoxCollider2D>();
    rbody = GetComponent<Rigidbody2D>();
}

public IEnumerator CastHookshot(float castDistance, Vector2 aimDir, GameObject playerInstance)
{
    player = playerInstance;
    playerPos = gameObject.transform.position;
    Vector2 target = playerPos + (castDistance * aimDir);
    float speed = castDistance / hookshotCastTime * Time.deltaTime;
    while (Vector2.Distance(transform.position, target) > hookshotDistanceBuffer)
    {
        //transform.position = Vector2.MoveTowards(transform.position, target, speed);
        rbody.velocity = speed * 10 * aimDir;
        yield return new WaitForFixedUpdate();
    }
    transform.position = target;
    StartCoroutine(ReturnHookshot());
}

public IEnumerator ReturnHookshot()
{
    col.enabled = false;
    playerPos = player.transform.position;
    while (Vector2.Distance(transform.position, playerPos) > hookshotDistanceBuffer)
    {
        playerPos = player.transform.position;
        transform.position = Vector2.MoveTowards(transform.position, playerPos, hookshotReturnSpeed * Time.deltaTime);

        yield return new WaitForEndOfFrame();
    }
    Destroy(gameObject);
}

//private void OnTriggerEnter2D(Collider2D collision)
//{
//    StopAllCoroutines();
//    Player playerInstance = player.GetComponent<Player>();
//    playerInstance.hookshotAttached = true;

//    if (GameManager.instance != null)
//    {
//        GameManager.instance.Emit(DustParticle, 5, transform.position, Vector2.one * 3f);
//    }

//}

private void OnCollisionEnter2D(Collision2D collision)
{
    StopAllCoroutines();
    rbody.velocity = Vector2.zero;
    Player playerInstance = player.GetComponent<Player>();
    playerInstance.hookshotAttached = true;

    if (GameManager.instance != null)
    {
        GameManager.instance.Emit(DustParticle, 5, transform.position, Vector2.one * 3f);
    }
}

}

【问题讨论】:

  • 这几乎可以肯定是因为物理在FixedUpdate 上,而你的协程在(有效地)Update 上。请改用WaitForFixedUpdate()
  • 我刚刚尝试了 WaitForFixedUpdate() 并没有改变任何东西

标签: c# unity3d


【解决方案1】:

尝试使用 TileMapCollider 向对象添加刚体并将其设置为运动学。碰撞事件应该在运动学刚体碰撞器和常规刚体碰撞器之间注册。此外,我没有看到任何监听 OnCollision 事件的代码。你能分享一些你对这两个对象的配置图片吗?

【讨论】:

  • 我按照@Draco18s 的建议更新了代码以包含 WaitForFixedUpdate(),现在我正在展示 OnCollisionEnter2D 函数
  • 我添加了 hookshot 对象和时间图对象的设置图片
  • 从运动学刚体对撞机更改您的钩子对象。在 Unity 中,两个运动学刚体不会产生碰撞事件。 Kinemtic 通常用于不经常移动的对象。 this 可能会有所帮助。您还应该添加一些打印语句以确保没有发生冲突。
  • 将 hookshot 设置为动态修复了该问题。谢谢你,赛斯。我一定会更仔细地阅读文档。
猜你喜欢
  • 1970-01-01
  • 2022-01-12
  • 2012-05-17
  • 2019-02-12
  • 1970-01-01
  • 2013-09-01
  • 2011-10-11
  • 2011-08-06
  • 2015-10-11
相关资源
最近更新 更多