Exemple #1
0
    private void SetOneBlock()
    {
        //혹시모르니 세팅시작할때 한번 비워주고 새로
        nearRandomValue.Clear();
        farRandomValue.Clear();
        rotationRandomValue.Clear();
        instructionPanel.SetActive(false);
        for (int i = 0; i < expRandomValue.NearPositionOffsetValues.Count; i++)
        {
            //랜덤한 index를 pop하는 식으로 랜덤값을 쓸거기때문에 한블럭을 시작할때마다 새로 복사해서 시작해야함, 원본을 지워버리면 이후에 못하기때문
            nearRandomValue.Add(expRandomValue.NearPositionOffsetValues[i]);
            farRandomValue.Add(expRandomValue.FarPositionOffsetValues[i]);
            rotationRandomValue.Add(expRandomValue.RotationOffsetValues[i]);
        }

        //한블럭 시작 초기화
        curExpCase = curExpFlow[ExperimentState.curBlockNum - 1];
        ExperimentState.curBlockDistance  = curExpCase.distance;
        ExperimentState.curBlockTechnique = curExpCase.technique;

        CSVManager.AppendToReport(CSVManager.GetReportLine("Block Start"));

        practiceCounter = 0;
        isPractice      = true;
        SetOnePractice();
    }
Exemple #2
0
 private void ReportPointerDown()
 {
     // 스마트폰에 가림막을 누르는 터치에대해서는 파일에 기록하지않기위해 if 문을 추가했음
     if (ExperimentState.curTrialPhase != TrialPhase.Null && guideChair.activeSelf)
     {
         CSVManager.AppendToReport(CSVManager.GetReportLine("press"));
     }
 }
Exemple #3
0
    public void StartExperiment()
    {
        ExperimentState.participantNum = expCtrPanel.participantNumber;
        ExperimentState.curBlockNum    = expCtrPanel.blockNumber;
        turnOffDuringExperiment.SetActive(false);
        curExpFlow = expAllFlow[ExperimentState.participantNum - 1];

        CSVManager.AppendToReport(CSVManager.GetReportLine("Experiment Start"));

        SetOneBlock();
    }
Exemple #4
0
    //연습모드
    private void SetOnePractice()
    {
        // SetOneTrial과 다른점은 랜덤값을 사용해도 리스트에서 삭제하지 않는다는점, 블럭종료까지 진행되는게 아니라 3회 후 바로 SetOneTrial실행으로 바로 이어진다는점, 끝내는 조건관련 변수들에 손대지않는다는점
        practiceCounter++;
        PV.RPC("RPC_OneTrialStart", RpcTarget.All); // trial 시작시마다 가림막 설치, 랜덤한 위치에 버튼생성을 위해 시작할때 신호를 보내줌
        manipChair.transform.localPosition = defaultManipChairPosition;
        manipChair.transform.localRotation = Quaternion.identity;

        ExperimentState.curTrialPhase = TrialPhase.RoughPlacement;

        // 랜덤 값 리스트에서 이번 Trial에 사용될 랜덤값 선정 실전과 다른점은 리스트에서 뽑아서 써도 삭제시키지 않는다는점
        System.Random random = new System.Random();
        int           index;

        if (ExperimentState.curBlockDistance == Distance.Near)
        {
            index = random.Next(nearRandomValue.Count);
            ExperimentState.curPositionOffset = nearRandomValue[index];
        }
        else
        {
            index = random.Next(farRandomValue.Count);
            ExperimentState.curPositionOffset = farRandomValue[index];
        }
        index = random.Next(rotationRandomValue.Count);
        ExperimentState.curRotationOffset = rotationRandomValue[index];

        // 배치와 돌리는 과정을 나눠서하기때문에 Que도 나눠서 두단계에 걸쳐서 줘야함, 여기서는 포지션 큐만, 로테이션은 상세배치 끝난후에
        guideChair.transform.localPosition = Vector3.zero;
        guideChair.transform.localRotation = Quaternion.identity;
        guideChair.transform.Translate(new Vector3(ExperimentState.curPositionOffset, 0, 0));

        // 테스트 할때는 주석처리하자
        guideChair.SetActive(false); // 스마트폰의 가림막을 1초 누르면 다시 킬거임

        CSVManager.AppendToReport(CSVManager.GetReportLine("Practice Trial Start"));
    }
Exemple #5
0
 // pointer up 마다 호출
 // 한번의 trial에는 3가지의 페이즈가 있음, 사용자 입력때마다 상태체크 or 정답체크하는 파트, 특정상태 or 정답이면 상호작용모드만 바꿔주면 된다.
 public void PhaseCheck()
 {
     if (ExperimentState.curTrialPhase == TrialPhase.RoughPlacement)
     {
         // 그냥 시선배치니까 어느정도 근처에 배치되면 ok
         float distance = Vector3.Distance(guideChair.transform.position, manipChair.transform.position);
         if (distance < 2f)
         {
             CSVManager.AppendToReport(CSVManager.GetReportLine("correct", distance));
             ExperimentState.curTrialPhase = TrialPhase.FinePlacement;
         }
     }
     else if (ExperimentState.curTrialPhase == TrialPhase.FinePlacement)
     {
         // 정답체크해서 맞으면 각도모드로 바꿔주고 아니면 말고
         float distance = Vector3.Distance(guideChair.transform.position, manipChair.transform.position);
         // 정답일때
         if (distance < 0.15f)
         {
             CSVManager.AppendToReport(CSVManager.GetReportLine("correct", distance));
             System.Random random = new System.Random();
             guideChair.transform.localRotation = Quaternion.identity;
             if (random.Next(2) == 0)
             {
                 guideChair.transform.Rotate(new Vector3(0, ExperimentState.curRotationOffset, 0));
             }
             else
             {
                 guideChair.transform.Rotate(new Vector3(0, -ExperimentState.curRotationOffset, 0));
             }
             ExperimentState.curTrialPhase = TrialPhase.Rotation;
         }
         else
         {
             //정답은 아닌데 화면에서 손 땟을때
             CSVManager.AppendToReport(CSVManager.GetReportLine("release", distance));
         }
     }
     else if (ExperimentState.curTrialPhase == TrialPhase.Rotation)
     {
         float angleGap = Vector3.Angle(guideChair.transform.forward, manipChair.transform.forward);
         // 정답체크해서 맞으면 다음 trial 호출 (세번째 페이즈까지 완료하면 다음 trial 호출)
         if (angleGap < 8f)
         {
             // 정답
             CSVManager.AppendToReport(CSVManager.GetReportLine("correct", angleGap));
             if (practiceCounter < practiceTimes)
             {
                 CSVManager.AppendToReport(CSVManager.GetReportLine("Practice Trial End"));
                 SetOnePractice();
             }
             else
             {
                 //연습 3회 한 후에는 정상모드로 돌입 (practiceCounter가 3일때 부터), isPractice는 Practice 끝남을 기록하는 동시에 SetOneTrial실행으로 바꿔줘야하기때문에 필요
                 if (isPractice)
                 {
                     CSVManager.AppendToReport(CSVManager.GetReportLine("Practice Trial End"));
                     isPractice = false;
                 }
                 else
                 {
                     CSVManager.AppendToReport(CSVManager.GetReportLine("Trial End"));
                 }
                 SetOneTrial();
             }
         }
         else
         {
             // 정답아닌데 손땟을때
             CSVManager.AppendToReport(CSVManager.GetReportLine("release", angleGap));
         }
     }
 }
Exemple #6
0
    //한블럭 10회 수행
    private void SetOneTrial()
    {
        ExperimentState.curTrialNum = 11 - rotationRandomValue.Count;
        PV.RPC("RPC_OneTrialStart", RpcTarget.All); // trial 시작시마다 가림막 설치, 랜덤한 위치에 버튼생성을 위해 시작할때 신호를 보내줌
        manipChair.transform.localPosition = defaultManipChairPosition;
        manipChair.transform.localRotation = Quaternion.identity;

        // Trial 10번하면 새로운 의자 생성을 멈춤, 설문시간을 가진후 다시 시작을 누르면 다음 Block을 실행 : 어느경우에느 사용되는 rotation random 갯수로, 거리는 near, far 경우가 갈림
        if (ExperimentState.curTrialNum > 10)
        {
            ExperimentState.curBlockDistance  = Distance.Null;
            ExperimentState.curBlockTechnique = Technique.Null;
            ExperimentState.curTrialNum       = -1;
            ExperimentState.curTrialPhase     = TrialPhase.Null;
            ExperimentState.curPositionOffset = -1;
            ExperimentState.curRotationOffset = -1;

            if (ExperimentState.curBlockNum == 6)
            {
                // 실험 종료
                ExperimentState.curBlockDistance  = Distance.Null;
                ExperimentState.curBlockTechnique = Technique.Null;
                ExperimentState.curTrialNum       = -1;
                ExperimentState.curTrialPhase     = TrialPhase.Null;
                ExperimentState.curPositionOffset = -1;
                ExperimentState.curRotationOffset = -1;
                CSVManager.AppendToReport(CSVManager.GetReportLine("Block End"));
                CSVManager.AppendToReport(CSVManager.GetReportLine("Experiment End"));
                instruction.SetText($"<size=35><b>All trials are over</b></size>\n\nPlease call coordinator and fill out the questionnaire.");
                nextBlockBtn.SetActive(false);
            }
            else if (ExperimentState.curBlockNum < 6)
            {
                // Block블록 종료
                ExperimentState.curBlockDistance  = Distance.Null;
                ExperimentState.curBlockTechnique = Technique.Null;
                ExperimentState.curTrialNum       = -1;
                ExperimentState.curTrialPhase     = TrialPhase.Null;
                ExperimentState.curPositionOffset = -1;
                ExperimentState.curRotationOffset = -1;
                CSVManager.AppendToReport(CSVManager.GetReportLine("Block End"));
                instruction.SetText($"<size=35><b>Block{ExperimentState.curBlockNum} is over</b></size>\n\nPlease call coordinator and fill out the questionnaire.");
                ExperimentState.curBlockNum++;
            }
            instructionPanel.SetActive(true);
            return;
        }

        // 한 trial의 첫 모드는 항상 시선으로 배치로 시작
        ExperimentState.curTrialPhase = TrialPhase.RoughPlacement;

        // 랜덤 값 리스트에서 이번 Trial에 사용될 랜덤값 선정
        System.Random random = new System.Random();
        int           index;

        if (ExperimentState.curBlockDistance == Distance.Near)
        {
            index = random.Next(nearRandomValue.Count);
            ExperimentState.curPositionOffset = nearRandomValue[index];
            nearRandomValue.RemoveAt(index);
        }
        else
        {
            index = random.Next(farRandomValue.Count);
            ExperimentState.curPositionOffset = farRandomValue[index];
            farRandomValue.RemoveAt(index);
        }
        index = random.Next(rotationRandomValue.Count);
        ExperimentState.curRotationOffset = rotationRandomValue[index];
        rotationRandomValue.RemoveAt(index);

        // 배치와 돌리는 과정을 나눠서하기때문에 Que도 나눠서 두단계에 걸쳐서 줘야함, 여기서는 포지션 큐만, 로테이션은 상세배치 끝난후에
        guideChair.transform.localPosition = Vector3.zero;
        guideChair.transform.localRotation = Quaternion.identity;
        guideChair.transform.Translate(new Vector3(ExperimentState.curPositionOffset, 0, 0));

        // 테스트 할때는 주석처리하자
        guideChair.SetActive(false); // 스마트폰의 가림막을 1초 누르면 다시 킬거임

        CSVManager.AppendToReport(CSVManager.GetReportLine("Trial Start"));
    }