У меня проблема с дверями, когда они открываются, а потом я жду их закрытия - PullRequest
0 голосов
/ 08 марта 2019

Когда я вхожу в зону триггера, дверь открывается.

Если я останусь в зоне триггера после того, как через несколько секунд откроются двери, дверь закроется для меня. Но, по моей логике, двери должны оставаться открытыми, пока я нахожусь в зоне срабатывания. Дверь должна быть закрыта, начинайте закрываться только при выходе из зоны триггера.

Другая проблема заключается в том, что я слишком быстро двигаюсь внутри / снаружи зоны триггера двери. Когда я нахожусь в дверце, начинайте открываться, когда дверь открыта, если я быстро вернусь из области триггера и снова вернусь очень быстро, даже если дверь все еще открыта, она снова воспроизведет анимацию открытой двери. Я не уверен, как решить эту слишком быструю проблему входа / выхода.

Я думаю, логика должна быть очень простой.

  • Войдя в зону триггера, откройте дверь.

  • Если я остаюсь в зоне триггера, когда дверь открыта и открыта, не закрывайте дверь, пока я не выйду из области триггера, затем потратьте несколько секунд и начните закрывать дверь.

  • Если дверь начала закрываться, а я вхожу в зону триггера, снова откройте дверь в том месте, где она находится, даже если она находится в середине закрытия.

  • Если я быстро очень быстро войду / выйду из области триггера двери, продолжайте в том же духе, как в первых двух правилах. И не воспроизводите анимацию открытой двери, если дверь уже открыта и уже открыта. Что делать, если игра идет?

Скрипт Doors Manager прикреплен к пустому GameObject:

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 прикреплен к дочернему имени двери Horizontal_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_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();
    }
}

Первый скриншот, показывающий пример конструкции двери. И инспектор Horizontal_Doors_Kit:

Door

На втором и последнем скриншоте показан один из инспекторов Door_Left. Значения скрипта и настроек одинаковы для Door_Left и Door_Right:

Door

У моего персонажа в FPSController есть жесткое тело, прикрепленное к коллайдеру, чтобы вызвать дверь.

1 Ответ

1 голос
/ 08 марта 2019

Но, по моей логике, двери должны оставаться открытыми, пока я нахожусь в зоне срабатывания.

Но не в вашей кодовой логике, ваша кодовая логика закрывает дверь после того, как дверь заканчивает открываться.

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

Вам нужно добавить OnTriggerLeave событие, чтобы закрыть дверь.

Второй вопрос связан с первым вопросом, поэтому, пожалуйста, сначала исправьте его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...