为什么组件会在 Unity 的碰撞事件中自动移除?

Why the component automatically was removed on collision event of the Unity?

我的英语水平很差,我的母语不是英语。 请理解。

我想做检测碰撞的逻辑

为此,我制作了一个角色class。 Character class继承了Unity系统的MonoBehaviour,具有如下特点

  1. class有容器放技能被自己撞到
  2. class有协程来显示容器的状态。当字符 class 启动时,此协同程序启动。
  3. class覆盖了Unity系统的OnTriggerEnter2D函数。在这个函数中,将与自己碰撞的技能添加到容器中。

我用下面的代码做了上面的功能。

public class Character : MonoBehaviour
{
    private ConcurrentDictionary<Skill, float> _skills = new ConcurrentDictionary<Skill, float>();


    protected virtual void Start()
    {
        StartCoroutine(Check());
    }

    private IEnumerator Check()
    {
        float delayTime = 0.1f;

    First:
        yield return new WaitForSeconds(delayTime);

        foreach (var skill in _skills.Keys.ToList())
        {
            Debug.Log($"_skills: {skill}");
        }

        goto First;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag != "cold_wind") return;

        var skill = collision.GetComponent<Skill>();
        _skills.TryAdd(skill, 100);
    }
}

然后我将 BoxCollider2D 组件添加到预制件中以添加上述角色 class。

然后我做了技能class。我省略了技能 class,因为技能 class 还没有功能。我将 BoxCollider2D 和 RigidBody2D 组件添加到预制件中以添加技能 class.

最后检查了RigidBody2D接收碰撞事件的Simulated函数

程序按以下顺序执行。

  1. 技能生成3秒,与角色碰撞
  2. Character的OnTriggerEnter2D函数被调用,碰撞的技能被添加到容器中。 (并发<技能, 浮动>)
  3. 检查协程显示技能被包含在容器中。

这里,我遇到了问题。逻辑上我认为容器中包含的技能 class 不能自动删除。

但3秒后(技能效果出现3秒)如果技能效果消失则容器中包含的技能class被移除。结果 Check 协程显示 null,如下所示。

谁能告诉我我做错了什么?

如有任何建议,我们将不胜感激。

感谢阅读。

很可能您所做的一切都按预期工作。一个错误是 TryAdd 的意外行为,其中添加的值可以是 null.

在您的 OnTriggerEnter2D 函数中,添加一个检查以确定您与什么发生碰撞以仅检查法术。最简单的方法是检查对象的 tag。对于你所有的法术,添加一个你可以检查的标签,然后改变你的碰撞代码看起来像

private void OnTriggerEnter2D(Collider2D collision)
{
    if(collision.gameObject.tag == "SpellTagHere")
    {
        // the issue is this line can result in NULL if another object collides with your player
        var skill = collision.GetComponent<Skill>();
        
        // meaning a null is added here
        _skills.TryAdd(skill, 100);
    }
}