using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using Random=System.Random; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Reflection; [StructLayout(LayoutKind.Sequential, Pack = 0)] public struct TimingSetting { public float TrialStart; public float TargetOnset; public float TargetOnsetDev; public float Go; public float MoveMax; public float HoldTime; }; public class ExperimentController : MonoBehaviour { public string TimingSettingFile = @"\Tables\Timings.csv"; public SpriteRenderer PlayerSprite; public GameObject[] Goals; private TimingSetting mTimingSetting; private string[] TableHeader; private float[] TableData; private ChangeColour[] GoalsChangeColour; private int ExperimentTrial = 0; private float Timer = 0f; private Random GoalSetter = new System.Random(300); private Random OnsetDeviator = new System.Random(100); private float OnsetDev = 0; private int GoalSet = 0; private const int NumGoals = 2; private GameObject Goal; void Awake() { GoalsChangeColour = new ChangeColour[Goals.Length]; } // Start is called before the first frame update void Start() { int length = Marshal.SizeOf (typeof(TimingSetting)); TableHeader = GetTableHeader(TimingSettingFile); TableData = GetTableFloat(TimingSettingFile); mTimingSetting = FloatArrayToStruct(TableData,mTimingSetting); PlayerSprite.enabled = true; for (int i = 0; i < Goals.Length; i++) { GoalsChangeColour[i] = Goals[i].GetComponent<ChangeColour>(); } /* GoalSet = GoalSetter.Next(NumGoals); */ /* OnsetDev = OnsetDeviator.Next(mTimingSetting.TargetOnsetDev); */ Debug.Log("GoalSet: " + GoalSet); } // Update is called once per frame void Update() { float dt = Time.deltaTime; // measure in ms Timer += dt*1000; if (Timer > mTimingSetting.TrialStart) { bool[] states = CheckGoalStates(GoalsChangeColour); bool flag = false; for (int i = 0; i < NumGoals; i++) { if (states[i]) { flag = true; } } if (!flag) { GoalSet = GoalSetter.Next(NumGoals); GoalsChangeColour[GoalSet].GoalState = 1; OnsetDev = OnsetDeviator.Next((int)mTimingSetting.TargetOnsetDev*2) - mTimingSetting.TargetOnsetDev; } } if (Timer > (mTimingSetting.TrialStart + mTimingSetting.TargetOnset + OnsetDev) ) { GoalsChangeColour[GoalSet].GoalState = 2; } // If the player is in the target start counting if (Timer > 3500) { ExperimentTrial++; GoalsChangeColour[GoalSet].GoalState = 0; } // If the player hasn't achieved the hold time in the allotted time // they fail } private string[] GetTableHeader(string filename) { string[] header; string table_file = @".\Assets\Scripts"; table_file = table_file + filename; using (var reader = new StreamReader(table_file)) { var line = reader.ReadLine(); header = line.Split(','); } return header; } private float[] GetTableFloat(string filename) { float[] data = new float[6]; string table_file = @".\Assets\Scripts"; table_file = table_file + filename; using (var reader = new StreamReader(table_file)) { reader.ReadLine(); var line = reader.ReadLine(); string []values = line.Split(','); for (int i = 0; i < values.Length; i++) { data[i] = Single.Parse(values[i]); } } return data; } private TimingSetting FloatArrayToStruct(float[] floatarray, TimingSetting structureObj) { int length = floatarray.Length; IntPtr ptr = Marshal.AllocHGlobal (length); Marshal.Copy (floatarray, 0, ptr, length); structureObj = (TimingSetting)Marshal.PtrToStructure (ptr, structureObj.GetType()); Marshal.FreeHGlobal (ptr); return structureObj; } private bool[] CheckGoalStates(ChangeColour[] GoalColours) { bool[] states = new bool[GoalColours.Length]; for (int i = 0 ; i < GoalColours.Length; i++) { if (GoalColours[i].GoalState > 0) { states[i] = true; } else { states[i] = false; } } return states; } }