Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using UnityEngine.UI;
- using System.Collections;
- using System.IO;
- public class BlockControl : MonoBehaviour
- {
- public bool DisplayFeedback;//whether or not we tell them correct answer after the click -- needd for prac but not for exp
- public float FeedbackDuration;// How long to display feedback (seconds)
- public int NumberOfBlocks;//number of blocks per condition (for me, maybe 2 if allow 3 breaks total)
- public float ITI;// Inter-trial interval (seconds) between trials within block
- public string[] randomized;//a bunch of "arc" and "sin" intermixed randomly
- public float[] rand1;//random variable for variance
- public float[] rand2;//random variable for variance
- public float[] rand3;//random variable for variance
- public bool editDone;//have triangles been drawn? (i.e. has edittriangles been called?)
- // Tracking stuff (recorded in output)
- public int CurrentBlock;//block number
- public string CurrentCondition;//arc or sin
- public int GlobalTrial;//global trial number
- public int TrialWithinBlock;//within-block trial number
- public string PracOrExp;//either "prac" or "exp"
- public string CompoundCondition;//"arclock" "arcleader" "curvylock" "curvyleader"
- public float x1,x2,x3,x4,x5,x6,x7,x8,x9,y1,y2,y3,y4,y5,y6,y7,y8,y9;//coordinates of 9 triangles
- public float StartTime;//start of trial
- public float OutClickTime1;//time of first click
- public float OutClickTime2;//time of second click
- public float VertClickPos;//y coordinate of second click
- // Experiment Info
- private int nConditions;//2 conditions (leader or lock)
- public string[] SetOfConditions;//leader or lock
- public string[] ConditionList;//randomized order of leader or lock
- private string[] PracOrExpList;//preset with number of practice and number of experimental
- public int nPracBlocks;//1 practice block per condition
- public int nBlocks;//1 block per condition
- public int nPracTrials;//5 practice trials per block
- public int nTrialsPerBlock;//100 experimental trials per block
- private int[] trialCounts;//list of trial counts for each block -- used to know when block is over
- public int maxTrials;//total trials over all blocks (summation of trialcounts)
- // Flow Control crap
- private bool startOfTrial = false;
- private bool waitingOnFeedback = false;
- private bool waitingOnITI = false;
- // public bool listenForResponse = false;
- private bool readyToStart = false;
- public bool EndOfTrial = false;
- public bool EndOfBlock = false;
- public bool waitingOnCleanup = false;//routine that destroys all objects on screen -- bool controls cleanup
- private bool dotsOnScreen;
- private Vector2 clickLocation;
- private Vector2 intersectionPoint;//calculated center of mass
- private GameObject[] dotObjects;
- // Links to other Classes
- public DisplayInstructions DisplayInstructions;
- private StartExp StartExp;
- private curvy_lock_script curvylock;
- private curvy_leader_script curvyleader;
- private arc_lock_script arclock;
- private arc_leader_script arcleader;
- //add all the other ones too? like endexperiment writeout do we need those?
- private string[] SimpleOutputArray;//where simple output file lines are created
- private StreamWriter SimpleSW;//reference to other one inside StartExp
- public float trialDuration; // Length of a movement trial in seconds // like 7-7.5 seconds
- // Use this for initialization
- void Start ()
- {
- // Links to other Classes
- DisplayInstructions = this.GetComponentInParent<DisplayInstructions> ();
- StartExp = this.GetComponentInParent<StartExp> ();
- curvylock = this.GetComponentInParent<curvy_lock_script> () as curvy_lock_script;
- curvyleader = this.GetComponentInParent<curvy_leader_script> () as curvy_leader_script;
- arclock = this.GetComponentInParent<arc_lock_script> () as arc_lock_script;
- arcleader = this.GetComponentInParent<arc_leader_script> () as arc_leader_script;
- // Default Values
- DisplayFeedback = true;
- FeedbackDuration = 1.0f; // seconds
- ITI = 0.5f;
- CurrentBlock = 0;
- readyToStart = true;
- NumberOfBlocks = nConditions * (nPracBlocks + nBlocks);
- int i = 0; // counter for blocks
- trialCounts = new int[NumberOfBlocks]; // list of trial counts for each block
- PracOrExpList = new string[NumberOfBlocks]; // Mark each block as practice or experiment
- ConditionList = new string[NumberOfBlocks]; // locklockleaderleder or vice versa
- for (int nc = 0; nc < nConditions; nc++) {
- for (int np = 1; np <= nPracBlocks; np++) {
- trialCounts [i] = nPracTrials;
- PracOrExpList [i] = "Practice";
- ConditionList[i] = SetOfConditions[nc];
- i++;
- }
- for (int ne = 1; ne <= nBlocks; ne++) {
- trialCounts [i] = nTrialsPerBlock;
- PracOrExpList [i] = "Experiment";
- ConditionList[i] = SetOfConditions[nc];
- i++;
- }
- }
- //randomized list of 50 arcs and 50 curvys
- for(int j=1;j<=50;j++)
- randomized[j]="arc";
- for(int j=51;j<=100;j++)
- randomized[j]="curvy";
- System.Array.Sort(randomized, RandomSort);
- //now 1-100 are set with the experimental trials
- //but we want 1-5 to be practice, then 6-105 to be exp
- for(int j=105;j>=6;j--)
- randomized[j]=randomized[j-5];
- //now populate 1-5
- for(int j=1;j<=5;j++)
- {
- if (j%2==0) randomized[j]="arc";
- if (j%2==1) randomized[j]="curvy";
- }
- for(int j=1;j<=105;j++)
- {
- if (randomized[j]=="arc")
- {
- rand1[j] = Random.Range (0.050f,0.090f);
- rand2[j] = Random.Range (-0.007f,-0.009f);
- rand3[j] = Random.Range (1.0f,1.2f);
- }
- if (randomized[j]=="curvy")
- {
- rand1[j] = Random.Range (0.050f,0.090f);
- rand2[j] = Random.Range (0.130f,0.170f);
- rand3[j] = Random.Range (3.2f,4.8f);
- }
- }
- }
- // Update is called once per frame
- void FixedUpdate ()
- {
- dotsOnScreen = false;
- if (curvylock.dotsOnScreen==true||curvyleader.dotsOnScreen==true||
- arclock.dotsOnScreen==true||arcleader.dotsOnScreen==true)
- dotsOnScreen=true;
- //clickLocation = curvylock.clickLocation;
- //figure out how to make this work for everything
- // Deal with GUI info and start the first block
- if (readyToStart && StartExp.DoneWithTheGUI) {
- nConditions = SetOfConditions.Length;
- maxTrials = nConditions * ((nPracBlocks * nPracTrials) + (nBlocks * nTrialsPerBlock));
- // Debug.Log (initialTrialOrderList.Length);
- StartCoroutine (StartBlock ());//startcoroutine starts another function but on another thread
- //startblock starts the block lol
- readyToStart = false;//already started, don't start something that's still going
- }
- // End of Trial
- if (EndOfTrial == true & waitingOnCleanup == false & dotsOnScreen == true) {//trial's over, still stuff on screen we want to clean
- if (CompoundCondition=="curvylock") StartCoroutine (curvylock.cleanUpDots());
- if (CompoundCondition=="curvyleader") StartCoroutine (curvyleader.cleanUpDots());
- if (CompoundCondition=="arclock") StartCoroutine (arclock.cleanUpDots());
- if (CompoundCondition=="arcleader") StartCoroutine (arcleader.cleanUpDots());
- /*if (DisplayFeedback == true) {//if it's in practice
- StartCoroutine (WaitForFeedback ());//waits for feedback duration while LoadDotFamily shows feedback stuff
- }*/ // shouldn't need this because of wait function inside the 4 movement practice ifs
- // Save the data
- //Vector2 pxIntersectionPoint = Camera.main.WorldToScreenPoint (intersectionPoint);//"correct" point of intersection, concerted from unity coord
- //to screen coord
- //Vector2 pxClickLocation = Camera.main.WorldToScreenPoint (clickLocation);//click location, converted from unity coord to screen cord
- //float errorDistance = Mathf.Abs (pxIntersectionPoint.y - pxClickLocation.y);//distance between true intersection and click
- //Vector2 pxCenterOfEnclosingCircle = Camera.main.WorldToScreenPoint(LoadDotFamily.centerOfEnclosingCircle);
- //Vector2 pxCenterOfPointMass = Camera.main.WorldToScreenPoint(LoadDotFamily.centerOfPointMass);
- //right now set up so that calculation of center of mass/convex hull is in data analysis
- //if have time this week, just do here
- // HeaderLine = SimpleHeaderLine = "Experiment\tSID\tBlockNumber\tCondition\tPracOrExp\tGlobalTrialNo
- // \tTrialWithinBlock\
- // tx1\ty1\tx2\ty2\tx3\ty3\tx4\ty4" +
- // "x5\ty5\tx6\ty6\tx7\ty7\tx8\ty8\tx9\ty9\tTimeStart\tTimeClick1\tTimeClick2\tVertClickPos\tCenterOfMassVert"
- SimpleOutputArray = new string[] {
- StartExp.ExperimentName,
- StartExp.SID,
- CurrentBlock.ToString (),
- CurrentCondition,
- PracOrExp,
- GlobalTrial.ToString (),
- TrialWithinBlock.ToString (),
- x1.ToString (),y1.ToString (),x2.ToString (),y2.ToString (),x3.ToString (),y3.ToString (),
- x4.ToString (),y4.ToString (),x5.ToString (),y5.ToString (),x6.ToString (),y6.ToString (),
- x7.ToString (),y7.ToString (),x8.ToString (),y8.ToString (),x9.ToString (),y9.ToString (),
- StartTime.ToString (),
- OutClickTime1.ToString (),
- OutClickTime2.ToString(),
- VertClickPos.ToString()
- };
- string SimpleLine = string.Join ("\t", SimpleOutputArray);
- // Debug.Log (trialLine);
- StartExp.SimpleSW.WriteLine (SimpleLine);//writes to buffer, then to file because of auto flush
- //simple stuff is done, move on to complex
- //string[] dotArray = {
- // StartExp.ExperimentName,
- // StartExp.SID,
- // CurrentBlock.ToString (),
- // CurrentCondition,
- // PracOrExp,
- // GlobalTrial.ToString (),
- // TrialWithinBlock.ToString (),
- // dotObjects.Length.ToString ()
- //};
- //string dotOutputLine = string.Join ("\t", dotArray);
- //for (int i = 0; i < dotObjects.Length; i++) {
- // dotOutputLine = dotOutputLine + "\t" + dotObjects [i].transform.position.x.ToString () + "\t" + dotObjects [i].transform.position.y.ToString ();
- //}
- //StartExp.SimpleSW.WriteLine (dotOutputLine);
- StartExp.ComplexSW.Flush(); // Ensure the eye tracking output gets written to disk at least once a trial
- // ComplexSW will be collecting stuff 60 Hz, but only actually go to disk
- // here, which is per-trial. this entire if statement is end of trial stuff
- waitingOnCleanup = true;//CleanUpDots will change this to false in the background
- }
- if (EndOfTrial == true & waitingOnCleanup == false & dotsOnScreen == false) {//now screen is cleared
- // Check for end of trial
- if (TrialWithinBlock == trialCounts [CurrentBlock - 1]) {//if block is over
- // Call for end of block
- EndOfBlock = true;//see next if
- } else {
- // On to the next trial
- StartCoroutine (WaitForITI ());
- startOfTrial = true;
- }
- EndOfTrial = false;//we just started a new block or a new trial
- }
- if (EndOfBlock == true) {
- StartCoroutine (EndBlock ());//ends block (probably)
- }
- if (startOfTrial == true & waitingOnFeedback == false & waitingOnITI == false) {
- AdvanceTrial ();//no more feedback, no more waiting, move on to next trial
- }
- }
- IEnumerator StartBlock ()//starts block, "IEnumerator" is a coroutine thing :)
- {
- EndOfBlock = false;//block is starting
- CurrentBlock++;//started a new block, so increment
- CurrentCondition = ConditionList [CurrentBlock - 1];//matches condition to block number
- //CurrentCondition = "None"; <3 debug
- PracOrExp = PracOrExpList [CurrentBlock - 1];//matches prac/exp to block number
- TrialWithinBlock = 0;//reset
- if (CurrentBlock == 1) {//the 0th block, but it got incremented at the start and became 1-indexed
- yield return StartCoroutine (DisplayInstructions.StartExperimentMessage ());//please wait for a click
- }
- yield return StartCoroutine (DisplayInstructions.DisplayBlockInstructions (CurrentCondition, PracOrExp == "Practice"));
- //pracorexp is 1 or 0 thing
- yield return StartCoroutine (WaitForITI ());//chill for like a second
- AdvanceTrial ();//just first trial
- }
- IEnumerator EndBlock ()//ends block
- {
- EndOfBlock = false;//because we're ending it
- if (CurrentBlock == NumberOfBlocks) {//then we're done with everything
- yield return StartCoroutine (DisplayInstructions.EndOfExperimentMessage ());//and we end the experiment
- this.GetComponentInParent<EndExperiment> ().EndExperimentCleanup ();//kill everything
- } else {//we're not done and we need another block
- yield return StartCoroutine (DisplayInstructions.EndOfBlockMessage ());//kill current block
- StartCoroutine (StartBlock ());//do next block
- }
- }
- IEnumerator WaitForFeedback ()//waits for feedback
- {
- waitingOnFeedback = true;
- yield return new WaitForSeconds (FeedbackDuration);//wait for waitforseconds to finish (waits for return fro mthing)
- // FeedbackText.text = "";
- waitingOnFeedback = false;
- }
- IEnumerator WaitForITI ()//waits for the inter trial thing
- {
- waitingOnITI = true;
- yield return new WaitForSeconds (ITI);//wait x seconds between trials
- waitingOnITI = false;
- }
- void AdvanceTrial ()//go on to next trial
- {
- // Debug.Log ("AdvanceTrial started");
- GlobalTrial++;
- TrialWithinBlock++;//starts at 0, but gets incremented here to start at 1
- startOfTrial = false;//because we're starting it
- editDone = false;
- //currentDotCount = 12;
- //COME BACK AND FIX LATER WHEN OTHER SCRIPTS DONE
- //some condition gets changed and then fixedupdate goes apeshit
- //this.GetComponentInParent<InitiateTrial> ().StartTrial ();//starts trial
- //have something here that starts the animations and marks time at start of trial
- if (ConditionList[CurrentBlock]=="lock")//means lock
- //for now just use this to test curvylock, later will mean practice
- {
- if (randomized[TrialWithinBlock]=="arc")
- {
- CompoundCondition="arclock";
- }
- else if (randomized[TrialWithinBlock]=="curvy")
- {
- CompoundCondition="curvylock";
- }
- }
- if (ConditionList[CurrentBlock]=="leader")//means leader
- {
- if (randomized[TrialWithinBlock]=="arc")
- {
- CompoundCondition="arcleader";
- }
- else if (randomized[TrialWithinBlock]=="curvy")
- {
- CompoundCondition="curvyleader";
- }
- }
- if (PracOrExpList[CurrentBlock]=="Practice")
- {
- PracOrExp="Practice";
- }
- if (PracOrExpList[CurrentBlock]=="Experiment")
- {
- PracOrExp="Experiment";
- }
- }
- int RandomSort (string a, string b)//-1 or 1 function
- {
- return UnityEngine.Random.Range (-1, 1);
- }
- int[] reshuffle(int[] elements)//shuffle function
- {
- // Knuth shuffle algorithm :: courtesy of Wikipedia :)
- for (int t = 0; t < elements.Length; t++ )
- {
- int tmp = elements[t];
- int r = Random.Range(t, elements.Length);
- elements[t] = elements[r];
- elements[r] = tmp;
- }
- return elements;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement