diff --git a/Assets/Scripts/BodyLanguage/GazeInteraction.cs b/Assets/Scripts/BodyLanguage/GazeInteraction.cs new file mode 100644 index 0000000..299a1eb --- /dev/null +++ b/Assets/Scripts/BodyLanguage/GazeInteraction.cs @@ -0,0 +1,30 @@ +using UnityEngine; + +public class GazeInteraction : MonoBehaviour +{ + [SerializeField] LayerMask layerMask; + TimeManager timeManager; + float gazeReach = 50.0f; + // Start is called once before the first execution of Update after the MonoBehaviour is created + void Start() + { + timeManager = FindFirstObjectByType(); + } + + // Update is called once per frame + void Update() + { + RaycastHit hit; + Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * gazeReach, Color.yellow); + if(Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, gazeReach, layerMask)) + { + timeManager.SetIsLookingAtAudience((hit.collider.tag == "Audience")); + timeManager.SetIsLookingAtProjector((hit.collider.tag == "Projector")); + } + else + { + timeManager.SetIsLookingAtAudience(false); + timeManager.SetIsLookingAtProjector(false); + } + } +} diff --git a/Assets/Scripts/BodyLanguage/GazeInteraction.cs.meta b/Assets/Scripts/BodyLanguage/GazeInteraction.cs.meta new file mode 100644 index 0000000..e4498e2 --- /dev/null +++ b/Assets/Scripts/BodyLanguage/GazeInteraction.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 4dde0c6125aa3004999b97aca0329b24 \ No newline at end of file diff --git a/Assets/Scripts/BodyLanguage/HandInteraction.cs b/Assets/Scripts/BodyLanguage/HandInteraction.cs new file mode 100644 index 0000000..43fee5b --- /dev/null +++ b/Assets/Scripts/BodyLanguage/HandInteraction.cs @@ -0,0 +1,37 @@ +using UnityEngine; + +public class HandInteraction : MonoBehaviour +{ + [SerializeField] Transform leftHand, rightHand; + + TimeManager timeManager; + + const float ROTATION_BOUND_MIN = 40.0f; + const float ROTATION_BOUND_MAX = 80.0f; + + void Start() + { + timeManager = FindFirstObjectByType(); + } + + // Update is called once per frame + void Update() + { + Vector3 l_RotationAngles = leftHand.eulerAngles; + Vector3 r_RotationAngles = rightHand.eulerAngles; + + if(isHandDown(l_RotationAngles) && isHandDown(r_RotationAngles)) + { + timeManager.SetAreHandsDown(true); + } + else + { + timeManager.SetAreHandsDown(false); + } + } + + bool isHandDown(Vector3 rotVec) + { + return rotVec.x >= ROTATION_BOUND_MIN && rotVec.x <= ROTATION_BOUND_MAX; + } +} diff --git a/Assets/Scripts/BodyLanguage/HandInteraction.cs.meta b/Assets/Scripts/BodyLanguage/HandInteraction.cs.meta new file mode 100644 index 0000000..fdc1d97 --- /dev/null +++ b/Assets/Scripts/BodyLanguage/HandInteraction.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a522a00b25f33dd469e0dd89a37f806b \ No newline at end of file diff --git a/Assets/Scripts/BodyLanguage/TimeManager.cs b/Assets/Scripts/BodyLanguage/TimeManager.cs new file mode 100644 index 0000000..9b9d233 --- /dev/null +++ b/Assets/Scripts/BodyLanguage/TimeManager.cs @@ -0,0 +1,179 @@ +using System.Collections.Generic; +using TMPro; +using UnityEngine; + +public class TimeManager : MonoBehaviour +{ + [SerializeField] TextMeshPro elapsedText, audienceText, projectorText, warningText, handsDownText; + + bool isLookingAtAudience = false; + bool isLookingAtProjector = false; + bool isLookingAtNothing = false; + bool areHandsDown = false; + bool areHandsDisengaged = false; + + bool hasStarted = false; + + const float LOOKING_AT_NOTHING_LIMIT = 6.0f; + const float HANDS_DOWN_LIMIT = 10.0f; + + float elapsedTime = 0; + float audienceTime = 0; + float projectorTime = 0; + float handsDownTime = 0; + + float timeLookingAtNothing, timeDisengagedHands; + + int lookingAtNothing_num, disengagedHands_num = 0; + + private void Start() + { + timeLookingAtNothing = LOOKING_AT_NOTHING_LIMIT; + timeDisengagedHands = HANDS_DOWN_LIMIT; + if (warningText != null) + warningText.enabled = false; + } + + void Update() + { + //if (OVRInput.Get(OVRInput.RawButton.RIndexTrigger)) + // StartTime(); + //if (OVRInput.Get(OVRInput.RawButton.LIndexTrigger)) + // PauseTime(); + if (!hasStarted) + return; + + elapsedTime += Time.deltaTime; + elapsedText.text = "Elapsed: " + FormattedTime(elapsedTime) + " (" + lookingAtNothing_num.ToString() + ")"; + + if (isLookingAtAudience) + { + audienceTime += Time.deltaTime; + audienceText.text = "Audience: " + FormattedTime(audienceTime); + } + + if (isLookingAtProjector) + { + projectorTime += Time.deltaTime; + projectorText.text = "Projector: " + FormattedTime(projectorTime); + } + + if (areHandsDown) { + handsDownTime += Time.deltaTime; + timeDisengagedHands -= Time.deltaTime; + handsDownText.text = "Hands down: " + FormattedTime(handsDownTime) + " (" + disengagedHands_num.ToString() + ")"; + } + + if (!isLookingAtAudience && !isLookingAtProjector) + timeLookingAtNothing -= Time.deltaTime; + else + timeLookingAtNothing = LOOKING_AT_NOTHING_LIMIT; + + if (timeDisengagedHands <= 0) + { + if (!areHandsDisengaged) + { + disengagedHands_num++; + areHandsDisengaged = true; + } + } + else + { + areHandsDisengaged = false; + } + + if (timeLookingAtNothing <= 0) { + if(warningText != null) + warningText.enabled = true; + if (!isLookingAtNothing) { + lookingAtNothing_num++; + isLookingAtNothing = true; + } + } + else + { + if(warningText != null) + warningText.enabled = false; + isLookingAtNothing = false; + } + + } + string FormattedTime(float timeVal) + { + int minutes = Mathf.FloorToInt(timeVal / 60); + int decSeconds = Mathf.FloorToInt(timeVal / 10) % 6; + int seconds = Mathf.FloorToInt(timeVal % 10); + + return minutes.ToString() + ":" + decSeconds.ToString() + seconds.ToString(); + } + + /** + * These methods aren't needed to manipulate the TimeManager or collect data. + */ + #region Setter Methods + public void SetIsLookingAtAudience(bool val) { + isLookingAtAudience=val; + } + + public void SetIsLookingAtProjector(bool val) { + isLookingAtProjector=val; + } + + public void SetAreHandsDown(bool val) + { + areHandsDown=val; + if (!val) + { + timeDisengagedHands = HANDS_DOWN_LIMIT; + } + } + #endregion + + + /** + * Use these methods to start, stop, pause timer and retrieve the collected data. + */ + #region RELEVANT METHODS + public Dictionary CollectedData() { + + Dictionary data = new Dictionary { + { "gaze_elapsedTime" , elapsedTime.ToString() }, + { "gaze_audienceTime" , audienceTime.ToString() }, + { "gaze_projectorTime" , projectorTime.ToString() }, + { "gaze_lookingAtNothing_num", lookingAtNothing_num.ToString() }, + { "hands_handsDownTime", handsDownTime.ToString() }, + { "hands_disengagedHands_num", disengagedHands_num.ToString() } + }; + + return data; + } + + public void StartTime() + { + hasStarted = true; + } + + public void PauseTime() + { + hasStarted = false; + } + + public void ResetTime() + { + elapsedTime = 0; + audienceTime = 0; + projectorTime = 0; + handsDownTime = 0; + timeLookingAtNothing = LOOKING_AT_NOTHING_LIMIT; + timeDisengagedHands = HANDS_DOWN_LIMIT; + if(warningText != null) + warningText.enabled = false; + } + public void StopTime() + { + PauseTime(); + ResetTime(); + } + #endregion +} + diff --git a/Assets/Scripts/BodyLanguage/TimeManager.cs.meta b/Assets/Scripts/BodyLanguage/TimeManager.cs.meta new file mode 100644 index 0000000..2ca40dd --- /dev/null +++ b/Assets/Scripts/BodyLanguage/TimeManager.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: da84e0473f28b3543b7a2d37606610d3 \ No newline at end of file