eye-therapy-2 / Assets / Scripts / Testing / TransparencyScenario.cs
TransparencyScenario.cs
Raw
using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.UI;

public class TransparencyScenario : MonoBehaviour, IListener
{
    [Header("Parameters")]
    [SerializeField] bool runOnAwake = false;
    [Tooltip("Time before scenario starts after activation.")]
    [SerializeField] float warmupTime = 5f;
    [Tooltip("Time to dim fire in left eye.")]
    [SerializeField] float firstDisappearTime = 4f;
    [Tooltip("Transparency step")] //
    [SerializeField] float[] transparencies = { 0f, 0.2f, 0.4f, 0.6f, 1f };
    [Tooltip("Time to dim fire in left eye.")]
    [SerializeField] float decisionTime = 5f;
    [Tooltip("Time to dim fire in left eye.")]
    [SerializeField] float transitionTime = 4f;

    [Header("References")]
    [SerializeField] EyeSimulator eyes;
    [SerializeField] FireManager fireManager;
    [SerializeField] Slider fireLeft = null;
    [SerializeField] Slider fireRight = null;
    [SerializeField] Slider crosshairLeft = null;
    [SerializeField] Slider crosshairRight = null;
    [SerializeField] LayerMask fireLayerMask;

    public bool IsRunning { get; private set; } = false;

    private const string FILE_PATH = "/Results/Transparency.csv";
    private StreamWriter file;

    private void Awake()
    {
        file = new StreamWriter(Application.dataPath + FILE_PATH, false);
        file.WriteLine("time;transparency");
    }

    private void Start()
    {
        EventManager.Instance.AddListener(EVENT_TYPE.ON_FIRE_WON, this);
        if (runOnAwake) StartScenario();
    }

    private void Update()
    {
        if (Physics.Raycast(eyes.transform.position, eyes.TargetDirection, out RaycastHit hit, eyes.ViewDistance, fireLayerMask))
        {
            hit.collider.GetComponent<FireBehaviour>().LookAt();
        }
    }

    private void FixedUpdate()
    {
        if (IsRunning)
        {
            try
            {
                file.WriteLine($"{Time.time};{fireLeft.value.ToString().Replace(".", ",")}");
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                throw;
            }
        }
    }

    public void StartScenario()
    {
        IsRunning = true;
        StartCoroutine(Scenario());
    }

    public void CancelScenario()
    {
        IsRunning = false;
        StopAllCoroutines();
        Debug.Log("Finishing scenario.");
    }

    IEnumerator Scenario()
    {
        // Time to get ready
        Debug.Log("Get ready for transparency scenario...");
        yield return new WaitForSeconds(warmupTime);

        // Start
        Debug.Log("Transparency scenario started.");

        // Hide fire in left eye and crosshair in right eye
        float t = 0;
        while (t < firstDisappearTime)
        {
            fireLeft.value = crosshairRight.value = Mathf.Lerp(1, 0, t / firstDisappearTime);
            t += Time.deltaTime;
            yield return null;
        }
        fireLeft.value = crosshairRight.value = 0;

        int idx = 0;
        while (true)
        {
            yield return new WaitForSeconds(decisionTime);
            if (fireManager.CurrentFire.IsMissed && !fireManager.CurrentFire.IsIgnored)
            {
                idx = Mathf.Min(++idx, transparencies.Length - 1);
                Debug.Log("Player is missing the target. Decreasing transparency.");
            }
            else if (!fireManager.CurrentFire.IsMissed)
            {
                idx = Mathf.Max(--idx, 0);
                Debug.Log("Player is hitting the target. Increasing transparency.");
            }
            float currentValue = fireLeft.value;
            if (currentValue != transparencies[idx])
            {
                t = 0;
                while (t < transitionTime)
                {
                    fireLeft.value = crosshairRight.value = Mathf.Lerp(currentValue, transparencies[idx], t / transitionTime);
                    t += Time.deltaTime;
                    yield return null;
                }
                fireLeft.value = crosshairRight.value = transparencies[idx];
            }
        }
    }

    public void OnEvent<T>(EVENT_TYPE eventType, Component Sender, T param = default)
    {
        switch (eventType)
        {
            case EVENT_TYPE.ON_FIRE_WON:
                CancelScenario();
                break;
        }
    }

    private void OnDestroy()
    {
        if (IsRunning) CancelScenario();
        file.Close();
    }
}