Exemple #1
0
    /// <summary>
    /// Creates the file to be saved and saves to disk
    /// </summary>
    private void CreateFile()
    {
        ExperimentLog.Log("Creating file");
        var sb = new StringBuilder();

        //Append Exp result headers
        sb.AppendLine("Event_Time" + "," + "Timer_Time" + "," + "Participant_Id" + ","
                      + "Ball_Number" + "," + "Ball_Type" + "," + "Ball_Speed" + "," +
                      "Ball_Result [Miss->0|1 : MaybeHit->2 : HitPastHalf->3 : Goal->4]" + "," + "Game_Points" + "," + "Level");
        //Append Exp results
        foreach (var data in expResults)
        {
            sb.AppendLine(data.ToString());
        }
        //Append Log Headers
        sb.AppendLine("\n\n");
        sb.AppendLine("Event_Time" + "," + "Tag" + "," + "Message");
        //Append Log Results
        foreach (var data in LogFileList)
        {
            sb.AppendLine(data.ToString());
        }
        string modeStr = TactileAndAudio ? "_tac_aud_" : "_aud_";

        var path = EditorUtility.SaveFilePanel(
            "Save Experiment as CSV",
            "",
            nameField.text + modeStr + "_exp.csv",
            "csv");

        if (path.Length != 0)
        {
            File.WriteAllBytes(path, new UTF8Encoding().GetBytes(sb.ToString()));
        }
    }
Exemple #2
0
 /// <summary>
 /// Click listener that starts the game. Must have player press a button and the researcher press start
 /// </summary>
 private void StartExp()
 {
     ExperimentLog.Log("Attempted to Start Experiment");
     if (canPressStartButton && playerReady)
     {
         canPressStartButton = false;
         clockTimer.Start();
         startTime = DateTime.Now;
         StartNextBall(HitRes.hitNotPastHalf); //Starting game, params don't matter here.
         ResetGamePoints();
     }
 }
Exemple #3
0
    /// <summary>
    /// Pulls up a GUI menu and based on selected option saves a CSV file with the data and log file.
    /// </summary>
    private void SaveCSV()
    {
        newBallOk = false;
        //NumberSpeech.PlayAudio("thanks");
        //yield return new WaitForSeconds(2);
        AudioListener.pause = true;
        int option = EditorUtility.DisplayDialogComplex("Finish Experiment",
                                                        "Are you sure you want to finish this experiment?",
                                                        "Save",
                                                        "Cancel",
                                                        "Quit Without Saving");

        switch (option)
        {
        // Save
        case 0:
            Destroy(_currentBall);
            CreateFile();
            menuGameObject.SetActive(true);
            newBallOk = false;
            clockTimer.Stop();
            ResetExp();
            MenuScript.SetMainSelectableAndAudio();
            break;

        // Cancel.
        case 1:
            newBallOk = true;
            break;

        // Quit Without saving.
        case 2:
            Destroy(_currentBall);
            menuGameObject.SetActive(true);
            clockTimer.Stop();
            newBallOk = false;
            ResetExp();
            MenuScript.SetMainSelectableAndAudio();
            break;

        default:
            Debug.LogError("Unrecognized option.");
            ExperimentLog.Log("Error in save menu", tag: "Error");
            break;
        }
        AudioListener.pause = false;
        canPressButton      = true;
    }
Exemple #4
0
 public void DebugPrint(String s, DebugType d)
 {
     if (debug_type == DebugType.NONE)
     {
         return;
     }
     if (d == DebugType.ALL || d == debug_type || debug_type == DebugType.ALL)
     {
         if (s.Contains("connected"))
         {
             Debug.LogWarning(s);
             ExperimentLog.Log("Joycon Connected");
         }
         else
         {
             Debug.Log(s);
             ExperimentLog.Log(s, "Joycon");
         }
     }
 }
Exemple #5
0
    private void Start()
    {
        if (JoyconManager.Instance == null)
        {
            SceneManager.LoadSceneAsync("GlobalInit", LoadSceneMode.Single);
            return;
        }
        GameUtils.playState = GameUtils.GamePlayState.ExpMode;
        GameUtils.ballSpeedPointsEnabled = false;
        _currBallNumber = -1;
        CreateBallPosition();
        ShuffleArray();
        saveExpButton.onClick.AddListener(FinishExp);
        startExpButton.onClick.AddListener(StartExp);

        numberSpeech        = globalSpeechGameObject.GetComponent <NumberSpeech>();
        _audioSources       = GetComponents <AudioSource>();
        levelUpAudio        = _audioSources[14];
        BallScript.GameInit = false;
        playerReady         = false;
        batSound            = batObj.GetComponents <AudioSource>()[0];
        batSound.mute       = true;
        StartCoroutine(GameUtils.PlayIntroMusic());
        newBallOk            = true;
        canPressButton       = true;
        clockTimer           = new Timer(100);
        clockTimer.Elapsed  += ClockTimer_Elapsed;
        globalTimer          = new Timer(100);
        globalTimer.Elapsed += GlobalTimer_Elapsed;
        globalTimer.Start();
        ExperimentLog.Log("Program Started", time: DateTime.Now.ToLongTimeString());
        gamePoints          = 0;
        canPressStartButton = true;
        expState            = ExpState.menus;
        playerLevel         = 0;
        past6Min            = false;
        prevHits            = new int[6] {
            0, 0, 0, 0, 0, 0
        };
        SetupChildAudio();
    }
Exemple #6
0
    /// <summary>
    /// Checks if a player can level by checking if the last 6 hits were hit or not.
    /// </summary>
    /// <returns></returns>
    private bool CheckLevelUp()
    {
        int hits = 0;

        foreach (int h in prevHits)
        {
            if (h == 1)
            {
                hits++;
            }
        }
        if (hits > 3) // 4 out of 6 hits, level up!
        {
            prevHits = new int[6] {
                0, 0, 0, 0, 0, 0
            };
            ExperimentLog.Log("Level Up: " + (playerLevel + 1), tag: "Exp");
            return(true);
        }
        return(false);
    }
Exemple #7
0
    /// <summary>
    /// Audio for next ball and calls spawnBall to start a new ball
    /// </summary>
    /// <returns></returns>
    private IEnumerator NextBallComing()
    {
        if ((UnityEngine.Random.Range(0, 3) == 0 && _currBallNumber != -1 && gamePoints != 1) ||
            _currBallNumber == 29)        //Randomly 1/3 of the time say how many points
        {
            ExperimentLog.Log("Read the Score");
            StartCoroutine(numberSpeech.PlayExpPointsAudio(gamePoints));
            yield return(new WaitForSeconds(4.5f)); //Wait 4.5 seconds for points audio to finish
        }
        else if (!IsAnnounceBall)
        {
            AudioSource aud = NumberSpeech.PlayAudio("nextball");
            yield return(new WaitForSeconds(aud.clip.length + 0.2f));
        }

        yield return(SpawnBall());

        timerStarted = true;
        oldTime      = Time.time;
        newBallOk    = true;
    }
Exemple #8
0
 /// <summary>
 /// Starts the next ball and adds to the total gamePoints
 /// </summary>
 /// <param name="hitres"></param>
 /// <param name="pointsToAdd"></param>
 private void StartNextBall(HitRes hitres)
 {
     if (playerReady && !canPressStartButton)
     {
         if (newBallOk)
         {
             newBallOk = false;
             Debug.Log("Sending Ball");
             ExperimentLog.Log("Sending Ball");
             if (_currBallNumber != -1)
             {
                 if (GoalScript.ExpBallWin)
                 {
                     GoalScript.ExpBallWin = false;
                     hitres = HitRes.goal;
                 }
                 gamePoints += hitres == HitRes.miss ? 0 : (int)hitres - 1;//The points correlate to the hitres
                 CollectExpData(hitres);
             }
             Destroy(_currentBall);
             if (_currBallNumber != -1)
             {
                 StartCoroutine((hitres != HitRes.miss && hitres != HitRes.tipped) ? NextBallHit() : NextBallMissed(hitres));
             }
             else
             {
                 StartCoroutine(NextBallComing());
             }
         }
     }
     else
     {
         Debug.LogWarning("Exp Not Started");
         ExperimentLog.Log("Exp Not Started", tag: "warn");
     }
 }
    private void SetupButtonClickListeners()
    {
        AudioOnlyButton.onClick.AddListener(() => {
            ExperimentLog.Log("Pressed Exp Mode", "Menu");
            ExpManager.TactileAndAudio = false;
            menuGameObject.SetActive(false);
            mainMenuGO.SetActive(true);
            expMenuText.text = "Audio Only Exp";
            Time.timeScale   = 1;
            if (!SceneManager.GetActiveScene().name.Equals("Master"))
            {
                SceneManager.LoadSceneAsync("Master", LoadSceneMode.Single);
            }
            currAudioList      = expAudioList;
            currSelectableList = expSelectableList;
            ToggleTopButton();
        });

        tactileAndAudioButton.onClick.AddListener(() =>
        {
            ExperimentLog.Log("Pressed Naive Mode", "Menu");
            ExpManager.TactileAndAudio = true;
            menuGameObject.SetActive(false);
            mainMenuGO.SetActive(true);
            Time.timeScale   = 1;
            expMenuText.text = "Tactile & Audio Exp";
            if (!SceneManager.GetActiveScene().name.Equals("Master"))
            {
                SceneManager.LoadSceneAsync("Master", LoadSceneMode.Single);
            }
            currAudioList      = expAudioList;
            currSelectableList = expSelectableList;
            ToggleTopButton();
        });

        freeButton.onClick.AddListener(() => {
            Time.timeScale = 1;
            ExperimentLog.Log("Pressed Free play Mode", "Menu");
            SceneManager.LoadSceneAsync("SinglePlayer", LoadSceneMode.Single);
        });

        startRightHand.onClick.AddListener(() =>
        {
            if (!partInputField.text.Equals(""))
            {
                ExperimentLog.Log("Clicked [Start Right Hand]", tag: "pre-menu");
                StartCalbMenu(false);
            }
            else
            {
                ExperimentLog.Log("Missing Participant ID", tag: "pre-menu");
                Debug.LogWarning("Missing Participant ID");
                GetComponents <AudioSource>()[1].Play();
            }
            currSelectableList = calibSelectableList;
            currAudioList      = calibAudioSourceList;
            ToggleTopButton();
        });

        startLeftHand.onClick.AddListener(() =>
        {
            if (!partInputField.text.Equals(""))
            {
                ExperimentLog.Log("Clicked [Start Right Hand]", tag: "pre-menu");
                StartCalbMenu(true);
            }
            else
            {
                ExperimentLog.Log("Missing Participant ID", tag: "pre-menu");
                Debug.LogWarning("Missing Participant ID");
                GetComponents <AudioSource>()[1].Play();
            }
            currSelectableList = calibSelectableList;
            currAudioList      = calibAudioSourceList;
            ToggleTopButton();
        });

        calibrateButton.onClick.AddListener(() =>
        {
            //If a JoyCon Button is pressed for the first time, then
            //the calibration in Exp Manager will be set.
            JoyconController.ButtonPressed = true;
            calibrationGO.SetActive(false);
            mainMenuGO.SetActive(true);
            currSelectableList = mainSelectableList;
            currAudioList      = mainAudioSouceList;
            ToggleTopButton();
        });
    }
Exemple #10
0
    /// <summary>
    /// Plays audio for a correction hint based on a hit result of the last ball
    /// This is a Coroutine menthod and by nature is async
    /// </summary>
    /// <param name="hitRes">The results of the last ball</param>
    /// <returns></returns>
    private IEnumerator ReadHitCorrection(HitRes hitRes)
    {
        var   snapShotBatPos  = endSnapshot.batPos;
        var   snapShotBallPos = endSnapshot.ballPos;
        float absDist         = Math.Abs(snapShotBatPos.x - snapShotBallPos.x);

        if (hitRes == HitRes.tipped)
        {
            if (CollisionSnapshot.ballPos.x < CollisionSnapshot.batPos.x - 5)
            {
                tippedAudio.Play();
                yield return(new WaitForSeconds(tippedAudio.clip.length));

                ExperimentLog.Log("Tipped to the left");
                reachLeft.Play();
                yield return(new WaitForSeconds(reachLeft.clip.length));
            }
            else if (CollisionSnapshot.ballPos.x > CollisionSnapshot.batPos.x + 5)
            {
                tippedAudio.Play();
                yield return(new WaitForSeconds(tippedAudio.clip.length));

                reachRight.Play();
                yield return(new WaitForSeconds(reachRight.clip.length));

                ExperimentLog.Log("Tipped to the right");
            }
            else if (CollisionSnapshot.ballPos.z < CollisionSnapshot.batPos.z)
            {
                ExperimentLog.Log("You hit the ball backward");
                backwardAudio.Play();
                yield return(new WaitForSeconds(backwardAudio.clip.length));
            }
        }
        else if (absDist < 10)
        {
            if (snapShotBatPos.z > snapShotBallPos.z)
            {
                //Reached too far forward too soon.
                tooForward.Play();
                yield return(new WaitForSeconds(tooForward.clip.length));
            }
            else
            {
                //Reached too far back
                tooBack.Play();
                yield return(new WaitForSeconds(tooBack.clip.length));
            }
        }
        else if (snapShotBallPos.x > 0 && snapShotBallPos.x > snapShotBatPos.x)
        {
            //Reach further to the right
            float distOff = snapShotBallPos.x - snapShotBatPos.x;
            reachRight.Play();
            yield return(new WaitForSeconds(reachRight.clip.length));

            StartCoroutine(numberSpeech.PlayFancyNumberAudio((int)distOff));
            yield return(new WaitForSeconds(2.5f));
        }
        else if (snapShotBallPos.x > 0 && snapShotBallPos.x < snapShotBatPos.x)
        {
            //Too far to the right
            float distOff = snapShotBatPos.x - snapShotBallPos.x;
            tooRight.Play();
            yield return(new WaitForSeconds(tooRight.clip.length));

            StartCoroutine(numberSpeech.PlayFancyNumberAudio((int)distOff));
            yield return(new WaitForSeconds(2.5f));
        }
        else if (snapShotBallPos.x < 0 && snapShotBallPos.x > snapShotBatPos.x)
        {
            //Too far to the left
            float distOff = Math.Abs(snapShotBatPos.x - snapShotBallPos.x);
            tooLeft.Play();
            yield return(new WaitForSeconds(tooLeft.clip.length));

            StartCoroutine(numberSpeech.PlayFancyNumberAudio((int)distOff));
            yield return(new WaitForSeconds(2.5f));
        }
        else if (snapShotBallPos.x < 0 && snapShotBallPos.x < snapShotBatPos.x)
        {
            //Reach futher to the left
            float distOff = Math.Abs(snapShotBallPos.x - snapShotBatPos.x);
            reachLeft.Play();
            yield return(new WaitForSeconds(reachLeft.clip.length));

            StartCoroutine(numberSpeech.PlayFancyNumberAudio((int)distOff));
            yield return(new WaitForSeconds(2.5f));
        }
        else if (snapShotBallPos.x == 0)
        {
            //Put it right in the middle
            middleAudio.Play();
            yield return(new WaitForSeconds(middleAudio.clip.length));
        }
        yield break;
    }