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

Unity横向门异常:首个门开启后无法关闭,后续门功能正常

问题分析与解决方案

我帮你找到了问题的核心根源,咱们一步步拆解:

问题所在

你的代码里使用了**静态变量HoriDoorManager.exitedDoor**来控制门的关闭逻辑,但静态变量是全局共享的,这就导致了第一个门的异常:

  1. 当玩家触发第一组门时,进入触发区调用OpenDoor,随后EndOpen启动WaitToClose协程——这时候玩家还在触发区内,exitedDoor还是false,协程里的if条件不满足,直接跳过了关门逻辑。
  2. 当玩家离开第一组门的触发区时,exitedDoor被设为true,但第一组门的协程已经结束了,所以永远不会关门。
  3. 后续的门触发时,exitedDoor已经是true,所以它们的WaitToClose协程能正常执行等待和关门操作。

修复方案

我们需要让每个门组独立管理自己的状态,不要依赖全局静态变量,同时调整协程的逻辑时机。

修改后的HoriDoorManager脚本

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

public class HoriDoorManager : MonoBehaviour {
    // 把全局静态变量改为实例变量,每个门组独立维护状态
    private bool exitedDoor = false;
    private bool doorLockState;
    private List<DoorHori> doors = new List<DoorHori>();

    private void Start() {
        if (transform.parent != null) {
            Transform parent = transform.parent;
            var children = parent.GetComponentsInChildren<Transform>();
            if(children != null) {
                foreach (Transform door in children) {
                    if (door.name == "Door_Left" || door.name == "Door_Right") {
                        DoorHori doorComp = door.GetComponent<DoorHori>();
                        doors.Add(doorComp);
                        // 把当前门组的Manager实例传给每个门,确保状态对应
                        doorComp.SetDoorManager(this);
                    }
                }
            }
        }
    }

    void OnTriggerEnter() {
        if (!doorLockState) {
            exitedDoor = false; // 进入触发区时重置离开状态
            foreach (var door in doors) {
                door.OpenDoor();
            }
        }
    }

    private void OnTriggerExit(Collider collide) {
        if (!doorLockState) {
            exitedDoor = true;
        }
    }

    public void ChangeLockState(bool lockState) {
        doorLockState = lockState;
    }

    // 给门提供获取当前门组离开状态的方法
    public bool HasExited() {
        return exitedDoor;
    }
}

修改后的DoorHori脚本

using UnityEngine;
using System.Collections;

public class DoorHori : MonoBehaviour {
    public float translateValue;
    public float easeTime;
    public OTween.EaseType ease;
    public float waitTime;
    private Vector3 StartlocalPos;
    private Vector3 endlocalPos;
    private HoriDoorManager doorManager; // 保存对应门组的Manager引用

    private void Start() {
        StartlocalPos = transform.localPosition;
        gameObject.isStatic = false;
    }

    // 让门组Manager设置自己的引用
    public void SetDoorManager(HoriDoorManager manager) {
        doorManager = manager;
    }

    public void OpenDoor() {
        OTween.ValueTo(gameObject, ease, 0.0f, -translateValue, easeTime, 0.0f, "StartOpen", "UpdateOpenDoor", "EndOpen");
        GetComponent<AudioSource>().Play();
    }

    private void UpdateOpenDoor(float f) {
        Vector3 pos = transform.TransformDirection(new Vector3(1, 0, 0));
        transform.localPosition = StartlocalPos + pos * f;
    }

    private void UpdateCloseDoor(float f) {
        Vector3 pos = transform.TransformDirection(new Vector3(-f, 0, 0));
        transform.localPosition = endlocalPos - pos;
    }

    private void EndOpen() {
        endlocalPos = transform.localPosition;
        StartCoroutine(WaitToClose());
    }

    private IEnumerator WaitToClose() {
        // 先等待指定时间,再检查是否已离开触发区(确保等待过程中玩家离开也能触发关门)
        yield return new WaitForSeconds(waitTime);
        if (doorManager != null && doorManager.HasExited()) {
            OTween.ValueTo(gameObject, ease, 0.0f, translateValue, easeTime, 0.0f, "StartClose", "UpdateCloseDoor", "EndClose");
            GetComponent<AudioSource>().Play();
        }
    }
}

关键修改点说明

  1. 移除全局静态状态:把exitedDoor从静态变量改为每个HoriDoorManager的实例变量,确保每个门组的状态独立,不会互相干扰。
  2. 门与门组的关联:让每个DoorHori持有对应门组的HoriDoorManager引用,保证它能获取到正确的触发区状态。
  3. 调整协程逻辑时机:把exitedDoor的检查从协程启动时移到等待之后,这样即使在等待过程中玩家离开触发区,也能正确触发关门操作。
  4. 重置状态:在玩家进入触发区时重置exitedDoor为false,确保每次触发的状态都是正确的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:25:51