using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.Audio; namespace InfallibleCode { public class DraggableWindow : MonoBehaviour, /*IDraggable*/ IInteractable { [Header("Type of window")] public Transform _Window; public bool WindowSmall; [Header("Window state")] public bool CanOpenWindow = true; public bool WindowIsOpen; public float WindowMin; private float WindowDefaultMin; public float WindowMax = 0.55f; [SerializeField] private float DrawSpeed = 1f; Vector3 _OpenPos; Vector3 _ClosedPos; public float _OpenPosition = 0.5f; public float _ClosedPosition = 0.0f; float posY; public float LerpWindow = 0f; public AudioSource windowAudioSource; public AudioMixer audioMixer; //public AudioClip windowOpenSoundEffect; //public AudioClip windowCloseSoundEffect; [Header("!DEBUGGING!")] public bool IsOpeningWindow; public bool IsClosingWindow; private float _OpenPositionWindowShort = 0.4f; public bool IsPullingDown; public bool IsPullingUp; public bool IsDraggingWindow; public bool CanForceWindowToClose = true; public bool ForceToCloseWindow; public bool IsForcingWindowToClose; public bool windowIsOpeningOrClosing; public UnityEvent AfterWindowGotClosedEvent; public UnityEvent AfterWindowGotUpEvent; public UnityEvent GlobalUnityEvent; public delegate void OnActionHappened(); public event OnActionHappened onWindowDown; public EventDelegateTrigger eventDelegateTriggerOnWindowDown; private void Awake() { if (gameObject.GetComponent() == null) { windowAudioSource = gameObject.AddComponent(typeof(AudioSource)) as AudioSource; // Assign the Audio Mixer to the AudioSource if (audioMixer != null) { windowAudioSource.outputAudioMixerGroup = audioMixer.FindMatchingGroups("SFX")[0]; } } //windowOpenSoundEffect = Resources.Load("WindowSounds/WindowOpen"); //windowCloseSoundEffect = Resources.Load("WindowSounds/WindowClose") as AudioClip; } void Start() { if (_Window == null) { _Window = GetComponent(); } WindowDefaultMin = _Window.localPosition.y; WindowMin = WindowDefaultMin; if (WindowSmall) //If the window is small: { _OpenPos = new Vector3(_Window.localPosition.x, _OpenPositionWindowShort, _Window.localPosition.z); } else //if it's not small: { _OpenPos = new Vector3(_Window.localPosition.x, WindowMax, _Window.localPosition.z); } _ClosedPos = new Vector3(_Window.localPosition.x, WindowMin, _Window.localPosition.z); if (WindowIsOpen) //If window should be open: { _Window.localPosition = new Vector3(0f, _OpenPosition, 0f); } } //private void Update() //{ // #region Force window to close // if (ForceToCloseWindow && !IsDraggingWindow && !DraggablesManager.GetInstance().IsDragging) //If it's forcing to close the window & is not dragging window or dragging in general: // { // ForceToCloseWindow = false; // IsForcingWindowToClose = true; // StartCoroutine(ForceCloseWindow()); // print("Force to close the window"); // } // if (WindowIsOpen && _Window.localPosition.y <= 0.05f && !IsDraggingWindow && !DraggablesManager.GetInstance().IsDragging && CanForceWindowToClose) // { // WindowIsOpen = false; //Window is not open. // ForceToCloseWindow = true; //Sets true the bool to start Forcing the window to close. // } // #endregion // if (/*DraggablesManager.GetInstance().*/IsDraggingWindow) //If you're dragging the window: // { // #region - Input (Negative) Open window // if (Input.GetAxis("Mouse Y") > 0 && DraggablesManager.GetInstance().IsDragging && !IsClosingWindow) // { // IsOpeningWindow = true; // IsClosingWindow = false; // LerpWindow += posY * Time.deltaTime; // } // else if (!IsClosingWindow) // { // IsOpeningWindow = false; // LerpWindow = 0f; // StopAllCoroutines(); //STOP OPENING DRAWER. // /*DraggablesManager.GetInstance().*/ // IsDraggingWindow = false; // print("Stop Opening window"); // } // #endregion // #region + Input (Positive) Close window // if (Input.GetAxis("Mouse Y") < 0 && DraggablesManager.GetInstance().IsDragging) // { // LerpWindow = Mathf.Abs(posY); // IsClosingWindow = true; // IsOpeningWindow = false; // LerpWindow += posY * Time.deltaTime; // } // else if (!IsOpeningWindow) // { // //IsClosingDrawer = false; // //LerpDrawer = 0f; // IsClosingWindow = false; // LerpWindow = 0f; // StopAllCoroutines(); //STOP OPENING DRAWER. // /*DraggablesManager.GetInstance().*/ // IsDraggingWindow = false; // print("Stop Closing window"); // } // #endregion // } //} public void DragWindow() { if (CanOpenWindow) { DraggablesManager.GetInstance().IsDragging = true; /*DraggablesManager.GetInstance().*/ IsDraggingWindow = true; posY = Input.GetAxis("Mouse Y") * DrawSpeed * Mathf.Deg2Rad; //The input of mouse drag. #region - Input (Negative) Open drawer //------------------ OPENING DRAWER ----------------------- if (IsOpeningWindow) { StopCoroutine(CloseWindow()); //STOP CLOSING DRAWER. StartCoroutine(OpenWindow()); } #endregion #region + Input (Positive) Close drawer //------------------ CLOSING DRAWER ----------------------- if (IsClosingWindow) { StopCoroutine(OpenWindow()); //STOP OPENING DRAWER. StartCoroutine(CloseWindow()); } #endregion } } public IEnumerator OpenWindow() { while (LerpWindow <= 1f) { _Window.localPosition = Vector3.Lerp(_Window.localPosition, _OpenPos, LerpWindow); if (_Window.localPosition.y >= 0.01f) { WindowIsOpen = true; } //if(transform.localPosition.y <= 0.05f) //{ // WindowIsOpen = false; //Window is not open. // ForceToCloseWindow = true; //Sets true the bool to start Forcing the window to close. //} print("Is opening Window"); yield return null; } } public IEnumerator CloseWindow() { while (LerpWindow <= 1f) { _Window.localPosition = Vector3.Lerp(_Window.localPosition, _ClosedPos, LerpWindow); if (_Window.localPosition.y <= 0.05f) //Forces to close the window if the value is smaller than the expected. { WindowIsOpen = false; //Window is not open. if (eventDelegateTriggerOnWindowDown != null) { eventDelegateTriggerOnWindowDown?.OnEventInvoke(); } onWindowDown?.Invoke(); if (AfterWindowGotClosedEvent != null) { AfterWindowGotClosedEvent.Invoke(); } ForceToCloseWindow = true; //Sets true the bool to start Forcing the window to close. } print("Is closing Window"); yield return null; } } public IEnumerator ForceCloseWindow() //Forces to close window. { while (LerpWindow <= 1f && IsForcingWindowToClose) { _Window.localPosition = Vector3.Lerp(_Window.localPosition, _ClosedPos, LerpWindow); LerpWindow += 0.5f * Time.deltaTime; if (_Window.localPosition.y <= 0f) { LerpWindow = 0f; IsForcingWindowToClose = false; } if (IsDraggingWindow && DraggablesManager.GetInstance().IsDragging) { LerpWindow = 0f; print("Window Force to Stop Coroutine is Stopped."); IsForcingWindowToClose = false; StopAllCoroutines(); } print("Is closing Window"); yield return null; } } //public void Drag() //{ // DragWindow(); //} public void Interact() { UpdateWindowState(); } private void UpdateWindowState() { if (CanOpenWindow && !windowIsOpeningOrClosing) { if (WindowIsOpen) { CloseThisWindow(1.5f); } else { OpenThisWindow(1.5f); } } } public void LockWindow() { CanOpenWindow = false; } public void UnlockWindow() { CanOpenWindow = true; } #region Open window from other scripts public void OpenThisWindow(float windowLerpSpeed) { RandomSoundsManager.GetInstance().PlayOpenWindowSound(windowAudioSource); //_Window.localPosition = new Vector3(0f, _OpenPosition, 0f); WindowIsOpen = true; CanForceWindowToClose = false; LerpWindow = 0f; StartCoroutine(OpenWindowCoroutine(windowLerpSpeed)); } IEnumerator OpenWindowCoroutine(float windowLerpSpeed) { Vector3 initialPos = _Window.localPosition; Vector3 targetPos = _OpenPos; // Calculate the transitionTime based on the windowLerpSpeed float transitionTime = Vector3.Distance(initialPos, targetPos) / windowLerpSpeed; windowIsOpeningOrClosing = true; while (LerpWindow <= transitionTime) { LerpWindow += /*windowLerpSpeed * */Time.deltaTime; float normalizedTime = Mathf.Clamp01(LerpWindow / transitionTime); //float lerpFactor = Mathf.Clamp01(windowLerpSpeed * Time.deltaTime); _Window.localPosition = Vector3.Lerp(initialPos, targetPos, normalizedTime); if (_Window.localPosition.y >= 0.05f) //It can force to close window again after the WindowPOS is larger than 0.05f; { CanForceWindowToClose = true; } float windowPos = _Window.transform.localPosition.y; //if (windowPos >= WindowMax) //{ // if (windowIsOpeningOrClosing) // { // windowIsOpeningOrClosing = false; // } // print("stop"); // StopAllCoroutines(); //} yield return null; } if(AfterWindowGotUpEvent != null) { AfterWindowGotUpEvent.Invoke(); } WindowIsOpen = true; windowIsOpeningOrClosing = false; } #endregion #region Close window from other scripts public void CloseThisWindow(float windowLerpSpeed) { //windowAudioSource.PlayOneShot(windowCloseSoundEffect); RandomSoundsManager.GetInstance().PlayCloseWindowSound(windowAudioSource); //_Window.localPosition = new Vector3(0f, _OpenPosition, 0f); WindowIsOpen = false; LerpWindow = 0f; StartCoroutine(CloseWindowCoroutine(windowLerpSpeed)); } IEnumerator CloseWindowCoroutine(float windowLerpSpeed) { Vector3 initialPos = _Window.localPosition; Vector3 targetPos = _ClosedPos; // Calculate the transitionTime based on the windowLerpSpeed float transitionTime = Vector3.Distance(initialPos, targetPos) / windowLerpSpeed; windowIsOpeningOrClosing = true; while (LerpWindow <= transitionTime) { LerpWindow += /*windowLerpSpeed * */Time.deltaTime; float normalizedTime = Mathf.Clamp01(LerpWindow / transitionTime); //float lerpFactor = Mathf.Clamp01(windowLerpSpeed * Time.deltaTime); _Window.localPosition = Vector3.Lerp(initialPos, targetPos, normalizedTime); float windowPos = _Window.transform.localPosition.y; if (windowPos <= WindowMin) { //if (windowIsOpeningOrClosing) //{ // if (eventDelegateTriggerOnWindowDown != null) // { // eventDelegateTriggerOnWindowDown?.OnEventInvoke(); // print("Event delegate OnWindowDown fired with name:" + eventDelegateTriggerOnWindowDown.name); // } // onWindowDown?.Invoke(); // if (AfterWindowGotClosedEvent != null) // { // AfterWindowGotClosedEvent.Invoke(); // print("AfterWindowGotClosedEvent fired"); // } // windowIsOpeningOrClosing = false; // print("Window closed."); //} //print("stop all coroutines on window close"); //StopAllCoroutines(); print("Window closed Pos reached"); } yield return null; } WindowIsOpen = false; //windowIsOpeningOrClosing = false; if (windowIsOpeningOrClosing) { if (eventDelegateTriggerOnWindowDown != null) { eventDelegateTriggerOnWindowDown?.OnEventInvoke(); print("Event delegate OnWindowDown fired with name:" + eventDelegateTriggerOnWindowDown.name); } onWindowDown?.Invoke(); if (AfterWindowGotClosedEvent != null) { AfterWindowGotClosedEvent.Invoke(); print("AfterWindowGotClosedEvent fired"); } windowIsOpeningOrClosing = false; print("Window closed."); } print("Window coroutine reached it's end"); } #endregion public void ForceWindowToClosePosition() { WindowIsOpen = false; _Window.localPosition = _ClosedPos; LerpWindow = 0f; if (AfterWindowGotClosedEvent != null) { AfterWindowGotClosedEvent.Invoke(); } } public void ForceWindowToOpenPosition() { WindowIsOpen = true; _Window.localPosition = _OpenPos; LerpWindow = 0f; if (AfterWindowGotUpEvent != null) { AfterWindowGotUpEvent.Invoke(); } } public void InvokeGotClosedEventEvent() { if (AfterWindowGotClosedEvent != null) { AfterWindowGotClosedEvent.Invoke(); } } public void InvokeAfterWindowGotUpEvent() { if (AfterWindowGotUpEvent != null) { AfterWindowGotUpEvent.Invoke(); } } } }