You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中玩家通过门传送直接跳至第三场景的问题求助

问题:穿过门时直接跳转到第三关卡

设置了3个关卡,通过Door对象实现玩家碰撞后传送至下一关卡,但玩家持续向前移动穿过门时,会直接传送至第三关卡。推测是OverlapCollider函数持续检测到碰撞导致多次触发传送逻辑,缩小门的Collider尺寸也无法解决。

相关代码如下:

Door 代码

public class Door : Collidable
{
    public string[] sceneNames;

    private static int sceneNumber = 0;

    protected override void OnCollide(Collider2D coll)
    {
        if(coll.name == "Player")
        {
            GameManager.instance.SaveState();

            //Teleport the player to next level
            sceneNumber++;

            if (sceneNumber >= sceneNames.Length)
            {
                return;
            }

            string sceneName = sceneNames[sceneNumber];
            SceneManager.LoadScene(sceneName);
        }
    }
}

Collidable 基类代码

public class Collidable : MonoBehaviour
{
    public ContactFilter2D filter;
    private BoxCollider2D boxCollider;
    private Collider2D[] hits = new Collider2D[10];

    protected virtual void Start()
    {
        boxCollider = GetComponent<BoxCollider2D>();
    }

    protected virtual void Update()
    {
        //Collision work
        boxCollider.OverlapCollider(filter,hits);
        for (int i = 0; i < hits.Length; i++)
        {
            if (hits[i] == null)
                continue;

            OnCollide(hits[i]);

            //The array is not cleaned up, so we do it ourself
            hits[i] = null; 
        }
    }

    protected virtual void OnCollide(Collider2D coll) 
    {
        Debug.Log("OnCollide was not implemented in " + this.name);
    }
}

碰撞体说明:门和玩家均使用BoxCollider2D,玩家移动时会持续与门的碰撞体重叠。


解决方案

方案1:改用触发事件替代持续检测

将门的Collider设置为Is Trigger,然后替换基类的检测逻辑为OnTriggerEnter2D,这样只会在碰撞开始时触发一次:

修改Collidable类:

public class Collidable : MonoBehaviour
{
    protected virtual void Start()
    {
        // 确保Collider设置为Is Trigger
        GetComponent<BoxCollider2D>().isTrigger = true;
    }

    protected virtual void OnTriggerEnter2D(Collider2D coll)
    {
        OnCollide(coll);
    }

    protected virtual void OnCollide(Collider2D coll) 
    {
        Debug.Log("OnCollide was not implemented in " + this.name);
    }
}

方案2:给门添加单次触发标记

如果不想修改基类检测逻辑,可以在Door类中添加标记,确保每个门只触发一次传送:

修改Door类:

public class Door : Collidable
{
    public string[] sceneNames;
    private static int sceneNumber = 0;
    // 添加触发标记
    private bool hasTriggered = false;

    protected override void OnCollide(Collider2D coll)
    {
        if(coll.name == "Player" && !hasTriggered)
        {
            hasTriggered = true;
            GameManager.instance.SaveState();

            sceneNumber++;

            if (sceneNumber >= sceneNames.Length)
            {
                return;
            }

            string sceneName = sceneNames[sceneNumber];
            SceneManager.LoadScene(sceneName);
        }
    }
}

额外优化:static场景计数器的潜在问题

sceneNumber使用static修饰,可能导致场景重新加载后计数器不会重置(比如玩家回到之前的关卡)。如果需要支持关卡回溯,可以将sceneNumber移到GameManager中管理,或者在场景加载时重置该值。


内容的提问来源于stack exchange,提问作者jonathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:20:37