Files
HauntedBloodlines/Assets/Scripts/Draggable/DraggableWindow.cs
2025-05-29 22:31:40 +03:00

480 lines
17 KiB
C#

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<AudioSource>() == 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<AudioClip>("WindowSounds/WindowOpen");
//windowCloseSoundEffect = Resources.Load("WindowSounds/WindowClose") as AudioClip;
}
void Start()
{
if (_Window == null)
{
_Window = GetComponent<Transform>();
}
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();
}
}
}
}