diff --git a/Assets/Non-VR Rig_Action Maps/PlayerInput.cs b/Assets/Non-VR Rig_Action Maps/PlayerInput.cs index 041a876..6312886 100644 --- a/Assets/Non-VR Rig_Action Maps/PlayerInput.cs +++ b/Assets/Non-VR Rig_Action Maps/PlayerInput.cs @@ -45,6 +45,15 @@ public @PlayerInput() ""processors"": """", ""interactions"": """", ""initialStateCheck"": false + }, + { + ""name"": ""Arrows"", + ""type"": ""PassThrough"", + ""id"": ""358655aa-723d-4b90-a8a3-c1badd8319a1"", + ""expectedControlType"": ""Key"", + ""processors"": """", + ""interactions"": """", + ""initialStateCheck"": false } ], ""bindings"": [ @@ -113,6 +122,28 @@ public @PlayerInput() ""action"": ""Look"", ""isComposite"": false, ""isPartOfComposite"": false + }, + { + ""name"": """", + ""id"": ""239c25d4-72f2-4e2a-9c83-0becced67f4f"", + ""path"": ""/leftArrow"", + ""interactions"": """", + ""processors"": """", + ""groups"": """", + ""action"": ""Arrows"", + ""isComposite"": false, + ""isPartOfComposite"": false + }, + { + ""name"": """", + ""id"": ""1f0a9fcd-54a6-468a-8f71-375c47a2e5bf"", + ""path"": ""/rightArrow"", + ""interactions"": """", + ""processors"": """", + ""groups"": """", + ""action"": ""Arrows"", + ""isComposite"": false, + ""isPartOfComposite"": false } ] } @@ -123,6 +154,7 @@ public @PlayerInput() m_Player = asset.FindActionMap("Player", throwIfNotFound: true); m_Player_Movement = m_Player.FindAction("Movement", throwIfNotFound: true); m_Player_Look = m_Player.FindAction("Look", throwIfNotFound: true); + m_Player_Arrows = m_Player.FindAction("Arrows", throwIfNotFound: true); } ~@PlayerInput() @@ -191,12 +223,14 @@ public int FindBinding(InputBinding bindingMask, out InputAction action) private List m_PlayerActionsCallbackInterfaces = new List(); private readonly InputAction m_Player_Movement; private readonly InputAction m_Player_Look; + private readonly InputAction m_Player_Arrows; public struct PlayerActions { private @PlayerInput m_Wrapper; public PlayerActions(@PlayerInput wrapper) { m_Wrapper = wrapper; } public InputAction @Movement => m_Wrapper.m_Player_Movement; public InputAction @Look => m_Wrapper.m_Player_Look; + public InputAction @Arrows => m_Wrapper.m_Player_Arrows; public InputActionMap Get() { return m_Wrapper.m_Player; } public void Enable() { Get().Enable(); } public void Disable() { Get().Disable(); } @@ -212,6 +246,9 @@ public void AddCallbacks(IPlayerActions instance) @Look.started += instance.OnLook; @Look.performed += instance.OnLook; @Look.canceled += instance.OnLook; + @Arrows.started += instance.OnArrows; + @Arrows.performed += instance.OnArrows; + @Arrows.canceled += instance.OnArrows; } private void UnregisterCallbacks(IPlayerActions instance) @@ -222,6 +259,9 @@ private void UnregisterCallbacks(IPlayerActions instance) @Look.started -= instance.OnLook; @Look.performed -= instance.OnLook; @Look.canceled -= instance.OnLook; + @Arrows.started -= instance.OnArrows; + @Arrows.performed -= instance.OnArrows; + @Arrows.canceled -= instance.OnArrows; } public void RemoveCallbacks(IPlayerActions instance) @@ -243,5 +283,6 @@ public interface IPlayerActions { void OnMovement(InputAction.CallbackContext context); void OnLook(InputAction.CallbackContext context); + void OnArrows(InputAction.CallbackContext context); } } diff --git a/Assets/Non-VR Rig_Action Maps/PlayerInput.inputactions b/Assets/Non-VR Rig_Action Maps/PlayerInput.inputactions index c047c0e..0a10935 100644 --- a/Assets/Non-VR Rig_Action Maps/PlayerInput.inputactions +++ b/Assets/Non-VR Rig_Action Maps/PlayerInput.inputactions @@ -22,6 +22,15 @@ "processors": "", "interactions": "", "initialStateCheck": false + }, + { + "name": "Arrows", + "type": "PassThrough", + "id": "358655aa-723d-4b90-a8a3-c1badd8319a1", + "expectedControlType": "Key", + "processors": "", + "interactions": "", + "initialStateCheck": false } ], "bindings": [ @@ -90,6 +99,28 @@ "action": "Look", "isComposite": false, "isPartOfComposite": false + }, + { + "name": "", + "id": "239c25d4-72f2-4e2a-9c83-0becced67f4f", + "path": "/leftArrow", + "interactions": "", + "processors": "", + "groups": "", + "action": "Arrows", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "1f0a9fcd-54a6-468a-8f71-375c47a2e5bf", + "path": "/rightArrow", + "interactions": "", + "processors": "", + "groups": "", + "action": "Arrows", + "isComposite": false, + "isPartOfComposite": false } ] } diff --git a/Assets/Prefabs/Arrow.prefab b/Assets/Prefabs/Arrow.prefab index dfb7ac4..fa5aa5a 100644 --- a/Assets/Prefabs/Arrow.prefab +++ b/Assets/Prefabs/Arrow.prefab @@ -396,7 +396,7 @@ MonoBehaviour: m_PreserveMeshAssetOnDestroy: 0 assetGuid: m_Mesh: {fileID: 0} - m_VersionIndex: 416 + m_VersionIndex: 419 m_IsSelectable: 1 m_SelectedFaces: m_SelectedEdges: [] diff --git a/Assets/Scenes/BasicScene.unity b/Assets/Scenes/BasicScene.unity index 93bafc8..d85696b 100644 --- a/Assets/Scenes/BasicScene.unity +++ b/Assets/Scenes/BasicScene.unity @@ -141,7 +141,7 @@ GameObject: - component: {fileID: 33726348} - component: {fileID: 33726349} m_Layer: 0 - m_Name: TestStart_TimedTest(Demo) + m_Name: TestStart_ReactionTest m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -1333,7 +1333,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4392ffc77a506104d80256dc28470f19, type: 3} m_Name: m_EditorClassIdentifier: - test: {fileID: 133065661} + test: {fileID: 370492606} colorChangeSpeed: 0.5 endColor: {r: 0, g: 0, b: 0, a: 0} --- !u!95 &33726348 @@ -1861,6 +1861,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 133065660} + - {fileID: 370492605} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &294338759 @@ -2522,6 +2523,54 @@ MonoBehaviour: m_LightCookieSize: {x: 1, y: 1} m_LightCookieOffset: {x: 0, y: 0} m_SoftShadowQuality: 0 +--- !u!1 &370492604 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 370492605} + - component: {fileID: 370492606} + m_Layer: 0 + m_Name: ReactionTest + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &370492605 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 370492604} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0.6790538, y: 1.4781137, z: -0.49147892} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 992329722} + - {fileID: 1145431398} + m_Father: {fileID: 273083091} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &370492606 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 370492604} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 06139d0a49ec7124a9143ceeabf246c0, type: 3} + m_Name: + m_EditorClassIdentifier: + leftArrow: {fileID: 992329716} + rightArrow: {fileID: 1145431392} --- !u!850595691 &404504638 LightingSettings: m_ObjectHideFlags: 0 @@ -2940,7 +2989,7 @@ GameObject: m_Component: - component: {fileID: 749134439} m_Layer: 0 - m_Name: TestStartContainer_TimedTest(Demo) + m_Name: TestStartContainer_ReactionTest m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -6686,12 +6735,12 @@ GameObject: - component: {fileID: 992329718} - component: {fileID: 992329717} m_Layer: 0 - m_Name: Arrow + m_Name: LeftArrow m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!64 &992329717 MeshCollider: m_ObjectHideFlags: 0 @@ -7163,11 +7212,11 @@ Transform: m_GameObject: {fileID: 992329716} serializedVersion: 2 m_LocalRotation: {x: -0.000002078712, y: -0.70710796, z: -0.7071057, w: 0.0000021234155} - m_LocalPosition: {x: -2.000001, y: 0.8749997, z: 1.1249979} + m_LocalPosition: {x: -0.5127349, y: -0.63475317, z: 2.0005155} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] - m_Father: {fileID: 0} + m_Father: {fileID: 370492605} m_LocalEulerAnglesHint: {x: -90, y: 0, z: -180} --- !u!1 &1045422745 GameObject: @@ -7715,6 +7764,16 @@ Transform: - {fileID: 1045422747} m_Father: {fileID: 294338760} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1145431392 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 8971293823169540501, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} + m_PrefabInstance: {fileID: 1220186818431017113} + m_PrefabAsset: {fileID: 0} +--- !u!4 &1145431398 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 2769561743914269895, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} + m_PrefabInstance: {fileID: 1220186818431017113} + m_PrefabAsset: {fileID: 0} --- !u!1 &1179475551 GameObject: m_ObjectHideFlags: 0 @@ -11900,7 +11959,7 @@ PrefabInstance: serializedVersion: 2 m_Modification: serializedVersion: 3 - m_TransformParent: {fileID: 0} + m_TransformParent: {fileID: 370492605} m_Modifications: - target: {fileID: 417905327810629334, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} propertyPath: m_Mesh @@ -11912,19 +11971,19 @@ PrefabInstance: objectReference: {fileID: 211118913} - target: {fileID: 467136503058936559, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} propertyPath: m_VersionIndex - value: 419 + value: 422 objectReference: {fileID: 0} - target: {fileID: 2769561743914269895, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} propertyPath: m_LocalPosition.x - value: -1 + value: 0.48726606 objectReference: {fileID: 0} - target: {fileID: 2769561743914269895, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} propertyPath: m_LocalPosition.y - value: 0.8749997 + value: -0.63475317 objectReference: {fileID: 0} - target: {fileID: 2769561743914269895, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} propertyPath: m_LocalPosition.z - value: 1.375 + value: 2.2505174 objectReference: {fileID: 0} - target: {fileID: 2769561743914269895, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} propertyPath: m_LocalRotation.w @@ -11960,7 +12019,11 @@ PrefabInstance: objectReference: {fileID: 211118913} - target: {fileID: 8971293823169540501, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} propertyPath: m_Name - value: Arrow + value: RightArrow + objectReference: {fileID: 0} + - target: {fileID: 8971293823169540501, guid: 05ac1c067e4dc2f41bd4a084a23e56e9, type: 3} + propertyPath: m_IsActive + value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] @@ -11980,5 +12043,3 @@ SceneRoots: - {fileID: 1108897244} - {fileID: 1950691295} - {fileID: 273083091} - - {fileID: 992329722} - - {fileID: 1220186818431017113} diff --git a/Assets/Scripts/ReactionTest.cs b/Assets/Scripts/ReactionTest.cs new file mode 100644 index 0000000..10edd8a --- /dev/null +++ b/Assets/Scripts/ReactionTest.cs @@ -0,0 +1,104 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.InputSystem; + +public class ReactionTest : TimedTest +{ + [SerializeField] protected GameObject leftArrow; + [SerializeField] protected GameObject rightArrow; + + public enum Reaction_curDirection { + NONE = 0, + LEFT, + RIGHT, + } + + protected int minWaitTime = 2; + protected int maxWaitTime = 3; + + protected float intervalTimer = 0f; + protected bool intervalTimerRunning = true; + + protected Reaction_curDirection curDirection = Reaction_curDirection.NONE; + + public override void UpdateTest() { + base.UpdateTest(); + + if (curDirection == Reaction_curDirection.NONE) { + if (intervalTimer <= 0) { + showArrow(); + startShowTime(); + intervalTimer = Random.Range(minWaitTime, maxWaitTime); + } else { + intervalTimer -= Time.deltaTime; + } + } else { + if (Keyboard.current.leftArrowKey.wasPressedThisFrame) { + if (curDirection == Reaction_curDirection.LEFT) { + correctAnswerGiven(); + } else { + wrongAnswerGiven(); + } + } else if (Keyboard.current.rightArrowKey.wasPressedThisFrame) { + if (curDirection == Reaction_curDirection.RIGHT) { + correctAnswerGiven(); + } else { + wrongAnswerGiven(); + } + } + } + } + + public override void InitializeTest() { + base.InitializeTest(); + + leftArrow.gameObject.SetActive(false); + rightArrow.gameObject.SetActive(false); + } + + public override float EndTest() { + leftArrow.gameObject.SetActive(false); + rightArrow.gameObject.SetActive(false); + + float lowestScore = getLowestScore(); + base.EndTest(); + return lowestScore; + } + + protected void showArrow() { + int left = Random.Range(0, 2); + + if (left != 0) { + curDirection = Reaction_curDirection.LEFT; + leftArrow.gameObject.SetActive(true); + } + else { + curDirection = Reaction_curDirection.RIGHT; + rightArrow.gameObject.SetActive(true); + } + } + + protected void hideArrow() { + if (curDirection == Reaction_curDirection.LEFT) { + leftArrow.gameObject.SetActive(false); + } else { + rightArrow.gameObject.SetActive(false); + } + curDirection = Reaction_curDirection.NONE; + } + + protected void correctAnswerGiven() { + Debug.Log("Correct"); + pauseSaveResetHideTime(); + hideArrow(); + intervalTimer = Random.Range(minWaitTime, maxWaitTime); + } + + protected void wrongAnswerGiven() { + Debug.Log("Wrong"); + pauseResetHideTime(); + hideArrow(); + intervalTimer = Random.Range(minWaitTime, maxWaitTime); + } +} diff --git a/Assets/Scripts/ReactionTest.cs.meta b/Assets/Scripts/ReactionTest.cs.meta new file mode 100644 index 0000000..27a3959 --- /dev/null +++ b/Assets/Scripts/ReactionTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06139d0a49ec7124a9143ceeabf246c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Test.cs b/Assets/Scripts/Test.cs index 58cd959..1d7dce0 100644 --- a/Assets/Scripts/Test.cs +++ b/Assets/Scripts/Test.cs @@ -5,14 +5,18 @@ // abstract test class for TestManager monobehaviour to polymorphically call functions of for any type of test derived from this class public abstract class Test : MonoBehaviour { - protected float score; + protected List scores = new List(); public Test() { - score = 0f; + } public Test(float score) { - setScore(score); + addScore(score); + } + + public Test(List scores) { + setScores(scores); } // what should be done to set up the test at the time the test is set active @@ -24,11 +28,77 @@ public Test(float score) { // destroys all objects created for test and returns the score public abstract float EndTest(); - protected void setScore(float score) { - this.score = score; + protected void clearScores() { + scores.Clear(); + } + + protected void addScore(float score) { + scores.Add(score); + } + + protected void addScores(List scores) { + for (int i = 0; i < scores.Count; ++i) { + this.scores.Add(scores[i]); + } + } + + protected void setScores(List scores) { + clearScores(); + + for (int i = 0; i < scores.Count; ++i) { + this.scores.Add(scores[i]); + } + } + + public float getScore(int index) { + if (index >= 0 && index < scores.Count) { + return scores[index]; + } else { + Debug.Log("Test class getScore() index of " + index + " was an invalid request due to an invalid index. The value 0 was returned."); + return 0f; + } + } + + public float getMostRecentScore() { + if (scores.Count > 0) { + return scores[scores.Count - 1]; + } else { + Debug.Log("Test class getMostRecentScore() cannot be executed since there are no scores currently in the scores list. The value 0 was returned."); + return 0f; + } + } + + public float getHighestScore() { + if (scores.Count > 0) { + float highestScore = scores[0]; + for (int i = 1; i < scores.Count; ++i) { + if (scores[i] > highestScore) { + highestScore = scores[i]; + } + } + return highestScore; + } else { + Debug.Log("Test class getHighestScore() cannot be executed since there are no scores currently in the scores list. The value 0 was returned."); + return 0f; + } + } + + public float getLowestScore() { + if (scores.Count > 0) { + float lowestScore = scores[0]; + for (int i = 1; i < scores.Count; ++i) { + if (scores[i] < lowestScore) { + lowestScore = scores[i]; + } + } + return lowestScore; + } else { + Debug.Log("Test class getLowestScore() cannot be executed since there are no scores currently in the scores list. The value 0 was returned."); + return 0f; + } } - public float getScore() { - return score; + public List getScores() { + return scores; } } diff --git a/Assets/Scripts/TimedTest.cs b/Assets/Scripts/TimedTest.cs index 5e7c3b3..1765319 100644 --- a/Assets/Scripts/TimedTest.cs +++ b/Assets/Scripts/TimedTest.cs @@ -7,9 +7,9 @@ // any test with a timer public class TimedTest : Test { - private float time = 0.0f; + protected float time = 0.0f; - private bool timerPaused = false; + protected bool timerPaused = false; private Canvas canvas; @@ -40,12 +40,76 @@ public override void InitializeTest() { timerText.GetComponent().anchoredPosition = new Vector3(0, 0, 0); } - // destroy timer text and return the time as score + // destroy timer text and return the lowest time as score public override float EndTest() { - score = time; - time = 0.0f; Destroy(timerText); - return score; + float lowestScore = getLowestScore(); + + clearScores(); + + return lowestScore; + } + + protected void pauseTimer() { + timerPaused = true; + } + + protected void startTimer() { + timerPaused = false; + } + + protected void toggleStartTimer() { + if (timerPaused) { + timerPaused = false; + } else { + timerPaused = true; + } + } + + protected void showTimer() { + timerText.gameObject.SetActive(true); + } + + protected void hideTimer() { + timerText.gameObject.SetActive(false); + } + + protected void toggleShowTimer() { + if (timerText.gameObject.activeInHierarchy) { + hideTimer(); + } else { + showTimer(); + } + } + + protected void saveTime() { + addScore(time); + } + + protected void resetTime() { + time = 0.0f; + } + + protected void saveAndResetTime() { + saveTime(); + resetTime(); + } + + protected void startShowTime() { + startTimer(); + showTimer(); + } + + protected void pauseResetHideTime() { + pauseTimer(); + resetTime(); + hideTimer(); + } + + protected void pauseSaveResetHideTime() { + pauseTimer(); + saveAndResetTime(); + hideTimer(); } }