Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity:如何以编程方式解决多个碰撞器导致评分问题的动画精灵?_C#_Unity3d - Fatal编程技术网

C# Unity:如何以编程方式解决多个碰撞器导致评分问题的动画精灵?

C# Unity:如何以编程方式解决多个碰撞器导致评分问题的动画精灵?,c#,unity3d,C#,Unity3d,我有一个动画精灵,它有8帧动画。每一帧都有一个PolygonCallider2D作为阵列的一个元素连接,因此无论播放哪一帧,都能为其提供精确的碰撞检测 当我在精灵上只有一个对撞机并且它通过“分数”对象时,玩家的分数增加了1分 private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.tag == "Point") { score++; scoreTe

我有一个动画精灵,它有8帧动画。每一帧都有一个PolygonCallider2D作为阵列的一个元素连接,因此无论播放哪一帧,都能为其提供精确的碰撞检测

当我在精灵上只有一个对撞机并且它通过“分数”对象时,玩家的分数增加了1分

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.gameObject.tag == "Point")
    {
        score++;
        scoreText.text = score.ToString();
        return;
    }
}

阵列中的每个碰撞器依次变为活动状态

public void SetColliderForSprite(int spriteNum)
{
    colliders[batColliderIndex].enabled = false;
    batColliderIndex = spriteNum;
    colliders[batColliderIndex].enabled = true;
}
现在动画的每一帧都有自己的对撞机,我发现分数以惊人的速度增加,因为每一帧在“分数”游戏对象内多次播放,在玩家离开该对象之前多次触发分数逻辑

我想知道理想的编程解决方案是什么,以确保在进入“点”碰撞器对象时,玩家在离开该区域之前只获得一次分数增量


提前感谢您的建议(如果在其他地方得到了答复,我表示歉意)。

编辑:我在考虑下面的帖子,我认为有一个更简单的解决方案。您应该能够设置碰撞器形状的动画,而不是每个动画帧有一个碰撞器。例如,请参见上的此问题

(作为旁注,您还可以在精灵的每个部分上有多个多边形碰撞器,并设置碰撞器的动画以相应地移动。例如,请参阅上的这篇文章。这种替代方法可能会使我在下面的文章中提出的建议更简单。)


我的一个建议是,只在检测到第一个
“点”
触发器时增加分数,然后在对象完全离开之前不再增加分数。这可以通过跟踪有多少碰撞器(或哪些特定碰撞器)进入和退出对象来实现。如下所示:

private const string PointTag = "Point";
private int _triggerCount;

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.gameObject.tag == PointTag)
    {
        bool firstCollision = (_triggerCount == 0);

        if (firstCollision)
        {
            score++;
            scoreText.text = score.ToString();
        }

        _triggerCount++;
    }
}

private void OnTriggerExit2D(Collider2D collision)
{
    if (collision.gameObject.tag == PointTag)
    {
        _triggerCount--;
    }
}
但是,一旦碰撞正在进行,您可能必须更改行为,以便所有碰撞器保持活动状态,直到对象完全离开碰撞区域。这是因为如果禁用碰撞器,
OnTriggerExit2D
事件将不会触发

此解决方案可能不可接受,具体取决于您检测
蝙蝠
离开碰撞区域的准确程度

如果不需要非常精确,可以通过添加第9个碰撞器来简化解决方案,该碰撞器具有覆盖精灵动画整个区域的唯一标记。通过使用第9个碰撞器来确定播放器何时离开碰撞区域,您不必担心会影响与显示每个动画帧的相应碰撞器相关的代码。(但请注意,必须修改此处的代码示例,以便
OnTriggerExit2D
使用此碰撞器对象。)


如果需要更精确,我认为可能会有一个类似于我建议的解决方案,基于当前激活的碰撞器、碰撞器形状和动画帧的详细信息,以及
OnTigerEnter2D
OnTiggerStay
OnTiggerExit2D
。但请注意,您可能还需要小心碰撞不会立即重新触发。(例如,对象可能已完全离开碰撞区域,但下一个动画帧可能会立即再次触发碰撞。)

感谢您的响应。你的编辑让我开始思考子对象。我添加了一个子碰撞器(索引值为9),然后检查是否与该子碰撞

引用了碰撞器阵列中的子碰撞器

之后,只需在播放器控制器脚本中引用它

// Update is called once per frame
void Update () {
    //Player input
    if (Input.GetMouseButtonDown(0))
    {
        bat.velocity = new Vector2(0, 4);
        //ADD BAT FLAP SOUND LATER!!!

    }
    scoreText.text = score.ToString();
    Debug.Log("SCORE: " + score);
}

//Point increment function
private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.gameObject.tag == "Point" && batColliderIndex == 9)
    {
        score++;
        return;
    }
}
我现在有了针对障碍物的像素完美碰撞检测和正确递增的分数


再次感谢。

很高兴我能帮忙!如果我的回答对你有帮助,请接受或投赞成票。