示例#1
0
 private void StartTask()
 {
     RecordData.Log("Starting task " + CurrentTaskIndex + " (" + (numTasksFinished + 1) + " / " + currentSequence.Length + ")");
     RecordData.CurrentRecord.taskStartTime = Time.realtimeSinceStartup;
     tasks[CurrentTaskIndex].gameObject.SetActive(true);
     tasks[CurrentTaskIndex].StartTask();
 }
示例#2
0
        private void NextSequence()
        {
            // Load new sequences in case old ones are all used up, which should not be a problem when using a file with all possible permutations.
            if (sequences == null || sequences.GetLength(0) == 0)
            {
                LoadSequences();
            }

            // Remember previous task in case we don't want to repeat it.
            int lastTask = (currentSequence == null) ? -1 : CurrentTaskIndex;

            int sequenceIndex;

            do
            {
                // Pick sequence and remove it from list of available sequences.
                sequenceIndex   = Random.Range(0, sequences.GetLength(0));
                currentSequence = sequences[sequenceIndex];
            } while (randomizeTasks && preventDirectRepetition && lastTask == currentSequence[0]);
            Assert.AreEqual(currentSequence.Length, tasks.Length);

            // This removes the used element, but it's quite ugly...
            var tmp = new List <int[]>(sequences);

            tmp.RemoveAt(sequenceIndex);
            sequences = tmp.ToArray();

            RecordData.Log("New task sequence is " + string.Join(", ", new List <int>(currentSequence).ConvertAll(i => i.ToString()).ToArray()));
        }
示例#3
0
 private void StartTutorials()
 {
     numTutorialsFinished = 0;
     runningTutorial      = true;
     RecordData.Log("Starting tutorial 0 (1/" + tutorials.Count
                    + ") with tutorial condition instead of condition "
                    + FindObjectOfType <ConditionSwitcher>().CurrentConditionIndex + ".");
     FindObjectOfType <ConditionSwitcher>().tutorialCondition.viewMode = "default";
     tutorials[0].gameObject.SetActive(true);
     tutorials[0].StartTask();
 }
示例#4
0
        private void SaveData()
        {
            RecordData.CurrentRecord.conditionIndex = FindObjectOfType <ConditionSwitcher>().CurrentConditionIndex;
            int currentTaskIdx = numTasksFinished % tasks.Length;

            RecordData.CurrentRecord.taskIndex = currentSequence[currentTaskIdx];

            if (RecordData.writeData)
            {
                RecordData.DumpToDisk(RecordData.UserFolder, "data_c_" + RecordData.CurrentRecord.conditionIndex + "_t_" + RecordData.CurrentRecord.taskIndex + ".txt");
            }
        }
示例#5
0
 public void NextCondition()
 {
     // Last condition was reached -> experiment is over!
     if (numConditionsFinished == conditions.Length - 1)
     {
         FindObjectOfType <TaskDisplay>().CurrentDescriptionID = "finished";
         RecordData.Log("All conditions completed. The experiment is over.");
     }
     else
     {
         ++numConditionsFinished;
         RecordData.Log("Starting condition " + CurrentConditionIndex + " (" + (numConditionsFinished + 1) + " / " + sequence.Length + ")");
     }
 }
示例#6
0
        private void Update()
        {
            FindObjectOfType <TaskDisplay>().SetLanguage(displayLanguage);

            if (!waitingForKeypress)
            {
                if (Input.GetKeyDown(KeyCode.X))
                {
                    RecordData.CurrentRecord.skipped             = !RecordData.CurrentRecord.skipped;
                    RecordData.CurrentRecord.skippedAfterSeconds = RecordData.CurrentRecord.skipped ? Time.realtimeSinceStartup - RecordData.CurrentRecord.taskStartTime : 0f;
                    RecordData.Log("Skip status of current task was marked as " + RecordData.CurrentRecord.skipped);
                }
                return;
            }

            if (runningTutorial)
            {
                // After start, tutorials need to be run by pressing Space or Return.
                FindObjectOfType <TaskDisplay>().CurrentDescriptionID = "waitTutorial";
                if (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.Return))
                {
                    waitingForKeypress = false;
                    StartTutorials();
                }
            }
            // Finished tutorials; waiting for experiment or repeating tutorials.
            else
            {
                FindObjectOfType <TaskDisplay>().CurrentDescriptionID = "waitExperiment";
                if (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.Return))
                {
                    waitingForKeypress = false;
                    NextSequence();
                    numTasksFinished = 0;
                    StartTask();
                }
                else if (!skipTutorials && tutorials.Count > 0 &&
                         numTasksFinished == 0 && // So that when pausing between experiment conditions, tutorials cannot be started.
                         (Input.GetKeyDown(KeyCode.Backspace) || Input.GetKeyDown(KeyCode.R)))
                {
                    runningTutorial = true;
                }
            }
        }
示例#7
0
        private void Awake()
        {
            var json   = conditionsJson.text;
            var config = JsonUtility.FromJson <ConditionConfiguration>(json);

            conditions = config.conditions;

            if (sequence == null || sequence.Length != conditions.Length)
            {
                Debug.LogWarning(conditionsJson.name + " defines " + conditions.Length + " conditions, but set sequence is invalid. Using default sequence.");
                sequence = new int[conditions.Length];
                for (int i = 0; i < sequence.Length; ++i)
                {
                    sequence[i] = i;
                }
            }

            RecordData.Log("Condition sequence is "
                           + string.Join(", ", new List <int>(sequence).ConvertAll(i => i.ToString()).ToArray())
                           + ", starting with condition "
                           + CurrentConditionIndex + " (" + (numConditionsFinished + 1) + " / " + sequence.Length + ")"
                           + ".");
        }
示例#8
0
文件: Task.cs 项目: Mowalle/megamap
 protected virtual void LogSubtask()
 {
     // FIXME: Not really the best approach for getting a distinct name.
     RecordData.Log("Starting subtask " + gameObject.name + ".");
 }
示例#9
0
        private void Update()
        {
            if (!IsStarted)
            {
                return;
            }

            var hand = laser.GetHand();

            if (acceptAction.GetStateDown(hand.handType) || Input.GetMouseButtonDown(0))
            {
                if (!laser.IsFrozen)
                {
                    laser.IsFrozen = true;
                    FindObjectOfType <TaskDisplay>().CurrentDescriptionID = "pointingConfirm";

                    startConfirmationTime = Time.realtimeSinceStartup;
                }
                else
                {
                    float endTime = Time.realtimeSinceStartup;

                    RecordData.CurrentRecord.pointingTime           = endTime - startTime;
                    RecordData.CurrentRecord.confirmationTime       = endTime - startConfirmationTime;
                    RecordData.CurrentRecord.positionAtConfirmation = Camera.main.transform.position;
                    RecordData.CurrentRecord.viewAtConfirmation     = Camera.main.transform.rotation.eulerAngles;
                    RecordData.CurrentRecord.rayPosition            = laser.Ray.origin;
                    RecordData.CurrentRecord.rayDirection           = laser.Ray.direction;

                    var hits = Physics.RaycastAll(laser.Ray, 200f);
                    foreach (var hit in hits)
                    {
                        // Go through all hits. If hit is room AND room is target, record related data.
                        // Second condition should always be true since we disabled all room colliders except for the target room.
                        if (hit.collider.GetComponent <SelectRoom>() != null && hit.collider.GetComponent <SelectRoom>().IsTargetRoom)
                        {
                            RecordData.CurrentRecord.hitRoom     = true;
                            RecordData.CurrentRecord.hitLocation = hit.point - hit.transform.position;
                            break;
                        }
                    }

                    var roomBounds = targetRoom.GetComponent <Renderer>().bounds;
                    // Determine pointing error towards room center.
                    Vector3 correctDir = (roomBounds.center - laser.Ray.origin).normalized;
                    Vector3 actualDir  = laser.Ray.direction.normalized;

                    // Positive horizontal angle means error to the right of center (from user POV), negative means left.
                    Vector2 correctProjHoriz = new Vector2(correctDir.z, correctDir.x);
                    Vector2 actualProjHoriz  = new Vector2(actualDir.z, actualDir.x);
                    float   horizAngle       = Vector2.SignedAngle(correctProjHoriz, actualProjHoriz);

                    // Positive horizontal angle means error over center (from user POV), negative means under.
                    Vector2 correctProjVert = new Vector2(correctDir.y, correctDir.z);
                    Vector2 actualProjVert  = new Vector2(actualDir.y, actualDir.z);
                    float   vertAngle       = Vector2.SignedAngle(correctProjVert, actualProjVert);

                    RecordData.CurrentRecord.horizOffsetDeg = horizAngle;
                    RecordData.CurrentRecord.vertOffsetDeg  = vertAngle;

                    RecordData.Log("Pointing error in degrees: " + horizAngle + ", " + vertAngle);

                    // Do next trial.
                    FindObjectOfType <TaskSwitcher>().NextTask();
                }
            }
            else if ((backAction.GetStateDown(hand.handType) || Input.GetKeyDown(KeyCode.Backspace)) && laser.IsFrozen)
            {
                laser.IsFrozen = false;
                FindObjectOfType <TaskDisplay>().CurrentDescriptionID = "pointingNormal";

                ++RecordData.CurrentRecord.numCorrections;
            }
        }
示例#10
0
        public void NextTask()
        {
            if (runningTutorial)
            {
                tutorials[numTutorialsFinished].StopTask();
                tutorials[numTutorialsFinished].gameObject.SetActive(false);

                ++numTutorialsFinished;
                if (numTutorialsFinished == tutorials.Count)
                {
                    runningTutorial    = false;
                    waitingForKeypress = true;
                    return;
                }
                RecordData.Log("Starting tutorial " + numTutorialsFinished
                               + " (" + (numTutorialsFinished + 1) + "/" + tutorials.Count
                               + ") with tutorial condition instead of condition "
                               + FindObjectOfType <ConditionSwitcher>().CurrentConditionIndex + ".");
                if (numTutorialsFinished % 2 != 0)
                {
                    FindObjectOfType <ConditionSwitcher>().tutorialCondition.viewMode = "flat";
                }
                else
                {
                    FindObjectOfType <ConditionSwitcher>().tutorialCondition.viewMode = "default";
                }

                tutorials[CurrentTaskIndex].gameObject.SetActive(true);
                tutorials[CurrentTaskIndex].StartTask();

                return;
            }

            // ------
            // The following will only be executed when all tutorials are finished.
            // ------

            tasks[CurrentTaskIndex].StopTask();
            tasks[CurrentTaskIndex].gameObject.SetActive(false);

            RecordData.CurrentRecord.taskEndTime  = Time.realtimeSinceStartup;
            RecordData.CurrentRecord.taskDuration = RecordData.CurrentRecord.taskEndTime - RecordData.CurrentRecord.taskStartTime;

            SaveData();

            if (numTasksFinished == tasks.Length - 1)
            {
                // Switch conditions.
                var condSwitcher  = FindObjectOfType <ConditionSwitcher>();
                int lastCondition = condSwitcher.CurrentConditionIndex;
                condSwitcher.NextCondition();
                // If conditions were not switched, it means all conditions were completed.
                // In that case, don't start the next task (there is none) and just keep the
                // task display and wait for user to take off HMD.
                if (lastCondition == condSwitcher.CurrentConditionIndex)
                {
                    return;
                }

                waitingForKeypress = true;
            }
            else
            {
                ++numTasksFinished;
                StartTask();
            }
        }