我在门打开时遇到问题,然后我正在等待它们关闭

Posted

技术标签:

【中文标题】我在门打开时遇到问题,然后我正在等待它们关闭【英文标题】:I have a problem with the doors when they open and then I'm waiting for them to close 【发布时间】:2019-03-08 02:19:33 【问题描述】:

一旦我进入触发区域,门就会打开。

如果我在几秒钟后门打开后留在触发区域内,门会在我身上关闭。但是按照我的逻辑,只要我在触发区域内,门就应该保持打开状态。只有离开触发区域时,门才会关闭。

另一个问题是,如果我在门的触发区域内外移动得太快。一旦我在门打开时开始打开门,如果我将快速移回触发区域并再次快速移回,即使门仍然打开,它也会再次播放开门动画。我不知道如何解决这个进入/退出太快的问题。

我觉得逻辑应该很简单。

进入触发区开门。

如果我在门完全打开时留在触发区域内,在我离开触发区域之前不要关门,然后花几秒钟时间开始关门。

如果门开始关闭,然后我进入触发区域,则在门现在的位置再次打开门,即使它正在关闭中。

如果我快速进入/退出门触发区域,请按照前两条规则进行处理。如果门已经打开并打开,则不要播放开门动画。如果该剧正在运行呢?

门管理器脚本附加到一个空的游戏对象:

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

public class DoorsManager : MonoBehaviour

    public List<HoriDoorManager> _doors = new List<HoriDoorManager>();

    private void Start()
    
        var doors = GameObject.FindGameObjectsWithTag("Door");
        foreach(var door in doors)
        
            _doors.Add(door.GetComponent<HoriDoorManager>());
        
    

    public void LockDoor(int doorIndex)
    
        _doors[doorIndex].ChangeLockState(true);
    
    public void UnlockDoor(int doorIndex)
    
        _doors[doorIndex].ChangeLockState(false);
    

脚本 Hori Door Manager 附加到门子名称 Horizo​​ntal_Doors_Kit:

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

public class HoriDoorManager : MonoBehaviour

    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")
                        doors.Add(door.GetComponent<DoorHori>());
                
            
        
    

    void OnTriggerEnter()
    
        if (doorLockState == false)
        
            if (doors != null)
            
               for(int i =0; i < doors.Count; i++)
                
                    doors[i].OpenDoor();
                
            
        
    

    public void ChangeLockState(bool lockState)
    
        doorLockState = lockState;
    

最后一个脚本 Door Hori 附加到门的每个子门。 门子名称为 Door_Keft 和 Door_Right,它们正在左右移动:

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 void Start()
        StartlocalPos = transform.localPosition;    
        gameObject.isStatic = false;
    

    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);
        OTween.ValueTo( gameObject,ease,0.0f,translateValue,easeTime,0.0f,"StartClose","UpdateCloseDoor","EndClose");
        GetComponent<AudioSource>().Play();
    

显示门结构示例的第一个屏幕截图。 以及 Horizo​​ntal_Doors_Kit 检查器:

第二个也是最后一个屏幕截图显示了一个 Door_Left 子检查器。 Door_Left 和 Door_Right 上的脚本和设置值相同:

我的角色 FPSController 有一个刚体,它连接了一个盒子碰撞器来触发门。

【问题讨论】:

【参考方案1】:

但按照我的逻辑,只要我在触发区域内,门就应该保持打开状态。

但不是在您的代码逻辑中,您的代码逻辑是在门打开后关闭门。

private void EndOpen()
    ....
    StartCoroutine( WaitToClose());

你需要添加OnTriggerLeave事件来关门。

第二个问题和第一个问题有关,请先修正。

【讨论】:

问题是 EndOpen 是从 OpenDoor 方法内的 OTween.ValueTo 行调用的。那么我如何从 OnTriggerLeave 内部调用 EndOpen ?这是调用 EndOpen 的行:OTween.ValueTo(gameObject,ease,0.0f,-translateValue,easeTime,0.0f,"StartOpen","UpdateOpenDoor","EndOpen"); 为什么要从OnTriggerLeave 拨打EndOpen?你说你的逻辑是:门应该是关闭的,只有在离开触发区域时才开始关闭

以上是关于我在门打开时遇到问题,然后我正在等待它们关闭的主要内容,如果未能解决你的问题,请参考以下文章

用JS关闭html5视频控件

有没有办法在关闭并再次打开时不重新创建表单的实例?

我需要为 Java 制作切换开关 [关闭]

在 Python 中等待 Windows 文件 I/O 完成

Cordova/Phonegap - 当我关闭应用程序时存储一个数组(当我重新打开时使用它们)

刷新/重新查询组合框问题