eye-therapy-2 / Assets / Scripts / Fireman / WaterHoseBehaviour.cs
WaterHoseBehaviour.cs
Raw
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class WaterHoseBehaviour : MonoBehaviour, IListener
{
    [SerializeField] private GameObject pump = null;
    [SerializeField] [Min(0f)] private float waterDrainSpeed = 1f;
    [SerializeField] [Min(0f)] private float waterPumpingSpeed = 1f;
    [SerializeField] private Gradient waterLevelTextColor = null;
    [Space]
    [SerializeField] private CanvasGroup waterLevelCanvasGroup = null;
    [SerializeField] private TextMeshProUGUI waterLevelText = null;
    [SerializeField] private Image waterLevelBarImage = null;
    [Space]
    [SerializeField] private TextMeshProUGUI secondaryWaterLevelText = null;
    [SerializeField] private Image secondaryWaterLevelBarImage = null;

    private ParticleSystem[] pSystems;
    private VRControlMode vrControlMode;
    public bool IsActive { get; private set; } = false;
    private float waterLevel = 1f;
    private float localWaterLevelShowSpeed = 0.2f;
    private Coroutine localWaterLevelShowFunc = null;

    private void Start()
    {
        pSystems = GetComponentsInChildren<ParticleSystem>();
        vrControlMode = (VRControlMode)PlayerPrefs.GetInt("VRControlMode", 1);
        OnEvent(EVENT_TYPE.ON_VR_CONTROLMODE_SWITCHED, this, vrControlMode);

        EventManager.Instance.AddListener(EVENT_TYPE.ON_FIRE_WON, this);
        EventManager.Instance.AddListener(EVENT_TYPE.ON_VR_CONTROLMODE_SWITCHED, this);
    }

    private void UpdateWaterLevelUI()
    {
        if (waterLevelText)
        {
            waterLevelText.text = string.Format("{0}%", (int)(waterLevel * 100));
            waterLevelText.color = waterLevelTextColor.Evaluate(waterLevel);
        }
        if (waterLevelBarImage) waterLevelBarImage.fillAmount = waterLevel;
        if (secondaryWaterLevelText)
        {
            secondaryWaterLevelText.text = string.Format("{0}%", (int)(waterLevel * 100));
            secondaryWaterLevelText.color = waterLevelTextColor.Evaluate(waterLevel);
        }
        if (secondaryWaterLevelBarImage) secondaryWaterLevelBarImage.fillAmount = waterLevel;
    }

    public void OnWaterHose(InputAction.CallbackContext ctx)
    {
        if (ctx.performed)
        {
            StartWaterHose();
        }
        else if (ctx.canceled)
        {
            StopWaterHose();
        }
    }

    public void StartWaterHose()
    {
        if (waterLevel > 0f)
        {
            for (int i = 0; i < pSystems.Length; i++)
            {
                pSystems[i].Play();
            }
            IsActive = true;
            if (vrControlMode == VRControlMode.Advanced && gameObject.activeSelf) StartCoroutine(DrainWater());
        }
    }

    public void StopWaterHose()
    {
        IsActive = false;
        for (int i = 0; i < pSystems.Length; i++)
        {
            pSystems[i].Stop();
        }
    }

    public void OnEvent<T>(EVENT_TYPE eventType, Component Sender, T param = default)
    {
        switch (eventType)
        {
            case EVENT_TYPE.ON_VR_CONTROLMODE_SWITCHED:
                vrControlMode = (VRControlMode)(dynamic)param;
                if (vrControlMode == VRControlMode.Basic)
                {
                    StopAllCoroutines();
                    StartCoroutine(ChangeWaterLevelOpacity(0f));
                    pump.SetActive(false);
                    waterLevel = 1f;
                }
                else if (vrControlMode == VRControlMode.Advanced)
                {
                    StopAllCoroutines();
                    StartCoroutine(ChangeWaterLevelOpacity(1f));
                    pump.SetActive(true);
                    UpdateWaterLevelUI();
                }
                break;
            case EVENT_TYPE.ON_FIRE_WON:
                gameObject.SetActive(false);
                break;
        }
    }

    public void ShowWaterLevel()
    {
        if (vrControlMode == VRControlMode.Advanced)
        {
            if (localWaterLevelShowFunc != null) StopCoroutine(localWaterLevelShowFunc);
            localWaterLevelShowFunc = StartCoroutine(ChangeWaterLevelOpacity(1f));
        }
    }

    public void HideWaterLevel()
    {
        if (vrControlMode == VRControlMode.Advanced)
        {
            if (localWaterLevelShowFunc != null) StopCoroutine(localWaterLevelShowFunc);
            localWaterLevelShowFunc = StartCoroutine(ChangeWaterLevelOpacity(0f));
        }
    }

    private IEnumerator ChangeWaterLevelOpacity(float targetValue)
    {
        float startValue = waterLevelCanvasGroup.alpha;
        float t = 0f;
        while(t < localWaterLevelShowSpeed)
        {
            t += Time.deltaTime;
            waterLevelCanvasGroup.alpha = Mathf.Lerp(startValue, targetValue, t / localWaterLevelShowSpeed);
            yield return null;
        }
        waterLevelCanvasGroup.alpha = targetValue;
        localWaterLevelShowFunc = null;
    }

    private IEnumerator DrainWater()
    {
        while(IsActive && waterLevel > 0f)
        {
            waterLevel = Mathf.Clamp01(waterLevel - Time.fixedDeltaTime * waterDrainSpeed);
            UpdateWaterLevelUI();
            if (waterLevel == 0f)
            {
                StopWaterHose();
            }
            yield return null;
        }
    }

    public void PumpWater(float value)
    {
        if (waterLevel < 1f)
        {
            waterLevel = Mathf.Clamp01(waterLevel + value * waterPumpingSpeed);
            UpdateWaterLevelUI();
        }
    }
}