immersivecognition / unity-experiment-framework

UXF - Framework for creating human behaviour experiments in Unity
https://immersivecognition.github.io/unity-experiment-framework/
MIT License
223 stars 44 forks source link

Pause between blocks skip first trial #161

Open cletess opened 9 months ago

cletess commented 9 months ago

Hi people,

I've been playing around a bit with UXF and Unity - starting from ground zero and I have managed to design a nice saccadic choice task with the Varjo Aero HMD, where we compare head movements and eye movements to targets.

I created a custom method to initiate a pause between blocks of trials and I call this method OnTrialEnd, checking if it's the last trial in the block. If it is, it pauses the experiment, displays a Canvas/UI interface with a couple of options like "eye-tracking calibration" and "proceed with the task".

All this works fine except for the part where the pause between blocks systematically skip the first trial of the second block (it's more as if the first trial was starting automatically in parallel with the UI interface) and I cannot figure out why. It must be something quite obvious but my coffee-injected brain cannot spot it.

Any help - advice on this would be greatly appreciated !

Here is the hierarchy of my task :

image

The different events :

image

and here is the method attached to the Canvas to deal with pauses between blocks :

using UnityEngine;
using TMPro;
using UXF;
using static UnityEngine.ParticleSystem;
using System;
using Varjo.XR;

public class InstructionsManager : MonoBehaviour
{
    private string blockInstructions;
    public GameObject canvas;
    public GameObject experiment;
    public TextMeshProUGUI instructionsText;

    public Session session;

    private void Awake()
    {
        canvas.SetActive(false);
    }

    // Call this instruction after generating your session OnSessionBegin to display the instructions for block 1
    public void ShowBlock1Instructions()
    {
        bool faceBlockFirst = (bool)session.participantDetails["face_block_first"];
        if (faceBlockFirst)
        {
            // Simulate starting a new block, customize instructions accordingly
            blockInstructions = "FOCUS ON FACES. Click 'I'm ready !' to proceed.";
        }
        else
        {
            // Simulate starting a new block, customize instructions accordingly
            blockInstructions = "FOCUS ON CARS. Click 'I'm ready !' to proceed.";
        }

        ShowInstructions(blockInstructions);
    }

    // Call this instruction OnTrialEnd to display the instructions for block 2 - it only shows it at the end of the last trial of block1
    public void ShowBlock2Instructions()
    {
        Trial trial = session.CurrentTrial;
        bool faceBlockFirst = (bool)session.participantDetails["face_block_first"];

        if (faceBlockFirst)
        {
            blockInstructions = "FOCUS ON CARS. Click 'I'm ready !' to proceed.";
        }
        else
        {
            blockInstructions = "FOCUS ON FACES. Click 'I'm ready !' to proceed.";
        }

        if (trial == trial.block.lastTrial)
        {
            // If this trial is the last trial of the block, do the following
            ShowInstructions(blockInstructions);
        }
    }

    public void ShowInstructions(string instructions)
    {
        // Enable the canvas
        canvas.SetActive(true);
        // Disable the experiment whilst the instructions are displayed
        experiment.SetActive(false);

        // Set instructions text properties
        if (instructionsText != null)
        {
            instructionsText.text = instructions;
            instructionsText.alignment = TextAlignmentOptions.Top; // Centered at the top
            instructionsText.fontSize = 2; // Font size 2 times the default
            instructionsText.lineSpacing = 20f; // Custom line spacing
        }
    }

    // OnClick Method for the button press - the method is invoked by the VR Laser Controller (see SteamVRLaserWrapper
    public void ButtonPress()
    {
        canvas.SetActive(false);
        VarjoEyeTracking.RequestGazeCalibration();
        experiment.SetActive(true);
    }
}
jackbrookes commented 9 months ago

Hi, I can't see any code here that actually starts the next trial. Maybe that would reveal more into your issue?

Perhaps you have some code that automatically starts the next trial after the last one ends? What you would need is some way to check if you should be pausing or not. If not, you not start the next trial and instead trigger the next trial when you've completed your pause.