diff --git a/Unity/Assets/Scenes/AR/AR-Task1.unity b/Unity/Assets/Scenes/AR/AR-Task1.unity index 770641e..4f60085 100644 --- a/Unity/Assets/Scenes/AR/AR-Task1.unity +++ b/Unity/Assets/Scenes/AR/AR-Task1.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e286b218eec091bce4bb95190b40ee739aae30605926d524b14ce1cfdd8ce997 -size 54374 +oid sha256:5b9a9f1429a8d0fceacc8453c29cbfc9883fca8d29abbaede0d65ae41d780d0d +size 63699 diff --git a/Unity/Assets/Scenes/AR/AR-Task2.unity b/Unity/Assets/Scenes/AR/AR-Task2.unity index 4df4d8d..ef3adb4 100644 --- a/Unity/Assets/Scenes/AR/AR-Task2.unity +++ b/Unity/Assets/Scenes/AR/AR-Task2.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6139c2517920c1f0a1a8d717f5cd4304b2ee45f0c6f8ece3f427fff63f68c31b -size 59323 +oid sha256:4e5f3d94adddb48e0c79ab6c9f641111b0715ba834c0eee44fa4a6b06772d87f +size 68618 diff --git a/Unity/Assets/Scenes/AR/AR-Task3.unity b/Unity/Assets/Scenes/AR/AR-Task3.unity index 7c6472f..d025776 100644 --- a/Unity/Assets/Scenes/AR/AR-Task3.unity +++ b/Unity/Assets/Scenes/AR/AR-Task3.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:609b300cd18fef5161ba8c4ddcf795249f95d1a2dd6db9d45c124891cc14f58b -size 59331 +oid sha256:b4d89eb20440ace56e3e131eebae1d6c898563fc35c5ad1bbcc04eb91927d2a0 +size 68650 diff --git a/Unity/Assets/Scenes/AR/AR-Task4.unity b/Unity/Assets/Scenes/AR/AR-Task4.unity index 6584ca7..a1d9ed5 100644 --- a/Unity/Assets/Scenes/AR/AR-Task4.unity +++ b/Unity/Assets/Scenes/AR/AR-Task4.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fda8b00122d0649e04401d330751e7198ebe066be45ed83f78075ac9e18c9425 -size 59331 +oid sha256:74634a1fd13f5b917f139bb51ca05006bd9cab4044b13766337024e9e92880ac +size 68668 diff --git a/Unity/Assets/Scenes/VR/VR -Task2.unity b/Unity/Assets/Scenes/VR/VR -Task2.unity index bac84d8..9d83df9 100644 --- a/Unity/Assets/Scenes/VR/VR -Task2.unity +++ b/Unity/Assets/Scenes/VR/VR -Task2.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e72fe9e2f613f0d2703c1126acf39ff1bd26a482b3bcc710627ce82c2bed16a -size 4628783 +oid sha256:0bd144016829f53049a0f55ba59fc026493c8b302007c302c2188690bf6c365d +size 4638112 diff --git a/Unity/Assets/Scenes/VR/VR -Task3.unity b/Unity/Assets/Scenes/VR/VR -Task3.unity index 2e38953..1417bec 100644 --- a/Unity/Assets/Scenes/VR/VR -Task3.unity +++ b/Unity/Assets/Scenes/VR/VR -Task3.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8fa0490c557f98924eff1688d643a8311d8ca0edd8eb6826c31185f8cfd8f82a -size 4628781 +oid sha256:d6368e6498099d7c7711e92831bd36c7e020bfbe4c9075de7a16a088dcc03aef +size 4638110 diff --git a/Unity/Assets/Scenes/VR/VR -Task4.unity b/Unity/Assets/Scenes/VR/VR -Task4.unity index e2bd977..d2503d7 100644 --- a/Unity/Assets/Scenes/VR/VR -Task4.unity +++ b/Unity/Assets/Scenes/VR/VR -Task4.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd700e3b5b4c7b9dcbcde908d1801af245fd2a2adc62672105dd763d0cb4a327 -size 4628781 +oid sha256:875949daa88974bc45774cf10cc208e22f0d0972c9e6e9b628443c5db42c81cd +size 4638110 diff --git a/Unity/Assets/Scenes/VR/VR-Task1.unity b/Unity/Assets/Scenes/VR/VR-Task1.unity index a8a5496..9fc513b 100644 --- a/Unity/Assets/Scenes/VR/VR-Task1.unity +++ b/Unity/Assets/Scenes/VR/VR-Task1.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1bb7817ffff2e1e15217f05750ecb87e3716478d491a12b5e57e1db34cedf6fd -size 4628788 +oid sha256:10a57751b2e69908ff65613defaf44b81f3b89ae7d1dc69e710a1d0f845d4c55 +size 4638695 diff --git a/Unity/Assets/Scripts/Editor.meta b/Unity/Assets/Scripts/Editor.meta new file mode 100644 index 0000000..f45945a --- /dev/null +++ b/Unity/Assets/Scripts/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dc569e3aee2d48840afbc77565086020 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/Scripts/Editor/TaskTimerSetup.cs b/Unity/Assets/Scripts/Editor/TaskTimerSetup.cs new file mode 100644 index 0000000..88edee0 --- /dev/null +++ b/Unity/Assets/Scripts/Editor/TaskTimerSetup.cs @@ -0,0 +1,122 @@ +using UnityEngine; +using UnityEditor; +using UnityEngine.UI; +using TMPro; + +public class TaskTimerSetup : EditorWindow +{ + private float taskDuration = 300f; + private bool useTextMeshPro = true; + private float canvasDistance = 2f; + private Vector3 canvasPosition = new Vector3(0, 1.5f, 2f); + + [MenuItem("Tools/Setup Task Timer for VR")] + public static void ShowWindow() + { + GetWindow("Task Timer Setup"); + } + + private void OnGUI() + { + GUILayout.Label("Task Timer VR Setup", EditorStyles.boldLabel); + GUILayout.Space(10); + + taskDuration = EditorGUILayout.FloatField("Task Duration (seconds)", taskDuration); + useTextMeshPro = EditorGUILayout.Toggle("Use TextMeshPro", useTextMeshPro); + canvasDistance = EditorGUILayout.FloatField("Distance from Camera", canvasDistance); + canvasPosition = EditorGUILayout.Vector3Field("Canvas Position", canvasPosition); + + GUILayout.Space(10); + + if (GUILayout.Button("Create Task Timer UI", GUILayout.Height(30))) + { + CreateTaskTimerUI(); + } + + GUILayout.Space(10); + EditorGUILayout.HelpBox( + "This will create:\n" + + "• World Space Canvas for VR\n" + + "• Timer display (TextMeshPro or UI Text)\n" + + "• TaskTimer script configured and ready\n\n" + + "The timer will automatically switch to Lobby scene when time expires.", + MessageType.Info); + } + + private void CreateTaskTimerUI() + { + // Create Canvas + GameObject canvasObj = new GameObject("TaskTimer_Canvas"); + Canvas canvas = canvasObj.AddComponent(); + canvas.renderMode = RenderMode.WorldSpace; + + CanvasScaler scaler = canvasObj.AddComponent(); + scaler.dynamicPixelsPerUnit = 10; + + canvasObj.AddComponent(); + + // Set canvas transform for VR + RectTransform canvasRect = canvasObj.GetComponent(); + canvasRect.sizeDelta = new Vector2(400, 100); + canvasRect.localScale = new Vector3(0.01f, 0.01f, 0.01f); + canvasRect.position = canvasPosition; + + // Create Panel Background + GameObject panelObj = new GameObject("Background_Panel"); + panelObj.transform.SetParent(canvasObj.transform, false); + + Image panelImage = panelObj.AddComponent(); + panelImage.color = new Color(0, 0, 0, 0.7f); + + RectTransform panelRect = panelObj.GetComponent(); + panelRect.anchorMin = new Vector2(0, 0); + panelRect.anchorMax = new Vector2(1, 1); + panelRect.sizeDelta = Vector2.zero; + + // Create Timer Text + GameObject textObj = new GameObject("Timer_Text"); + textObj.transform.SetParent(panelObj.transform, false); + + TaskTimer timerScript = canvasObj.AddComponent(); + timerScript.taskDuration = taskDuration; + timerScript.autoStart = true; + + RectTransform textRect; + + if (useTextMeshPro) + { + TextMeshProUGUI tmpText = textObj.AddComponent(); + tmpText.text = "00:00"; + tmpText.fontSize = 60; + tmpText.alignment = TextAlignmentOptions.Center; + tmpText.color = Color.white; + tmpText.font = Resources.Load("Fonts & Materials/LiberationSans SDF"); + + timerScript.timerTextTMP = tmpText; + textRect = textObj.GetComponent(); + } + else + { + Text legacyText = textObj.AddComponent(); + legacyText.text = "00:00"; + legacyText.fontSize = 60; + legacyText.alignment = TextAnchor.MiddleCenter; + legacyText.color = Color.white; + legacyText.font = Resources.GetBuiltinResource("Arial.ttf"); + + timerScript.timerTextLegacy = legacyText; + textRect = textObj.GetComponent(); + } + + // Configure RectTransform after UI component is added + textRect.anchorMin = new Vector2(0, 0); + textRect.anchorMax = new Vector2(1, 1); + textRect.sizeDelta = Vector2.zero; + + // Select the created object + Selection.activeGameObject = canvasObj; + + Debug.Log("Task Timer UI created successfully! Configure position as needed for your VR setup."); + } +} + diff --git a/Unity/Assets/Scripts/Editor/TaskTimerSetup.cs.meta b/Unity/Assets/Scripts/Editor/TaskTimerSetup.cs.meta new file mode 100644 index 0000000..c88100e --- /dev/null +++ b/Unity/Assets/Scripts/Editor/TaskTimerSetup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 83c1e1e5c642f3f4bbdb2d5b8d4a82fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Unity/Assets/Scripts/TaskTimer.cs b/Unity/Assets/Scripts/TaskTimer.cs new file mode 100644 index 0000000..aa51ffe --- /dev/null +++ b/Unity/Assets/Scripts/TaskTimer.cs @@ -0,0 +1,159 @@ +using UnityEngine; +using UnityEngine.UI; +using UnityEngine.SceneManagement; +using TMPro; + +public class TaskTimer : MonoBehaviour +{ + [Header("Timer Settings")] + [Tooltip("Total time for the task in seconds")] + public float taskDuration = 300f; // 5 minutes default + + [Tooltip("Start timer automatically on scene load")] + public bool autoStart = true; + + [Tooltip("Show warning when time is low (in seconds)")] + public float warningThreshold = 30f; + + [Header("UI References")] + [Tooltip("TextMeshPro component to display timer (recommended for VR)")] + public TextMeshProUGUI timerTextTMP; + + [Tooltip("Legacy UI Text component (if not using TextMeshPro)")] + public Text timerTextLegacy; + + [Header("Visual Settings")] + [Tooltip("Normal color for timer text")] + public Color normalColor = Color.white; + + [Tooltip("Warning color when time is running low")] + public Color warningColor = Color.red; + + [Tooltip("Format: 'MM:SS' or 'HH:MM:SS'")] + public bool showHours = false; + + private float timeRemaining; + private bool isRunning; + + private void Start() + { + timeRemaining = taskDuration; + + if (autoStart) + { + StartTimer(); + } + + UpdateTimerDisplay(); + } + + private void Update() + { + if (!isRunning) + return; + + timeRemaining -= Time.deltaTime; + + // Check if time is up + if (timeRemaining <= 0) + { + timeRemaining = 0; + OnTimerExpired(); + } + + UpdateTimerDisplay(); + } + + public void StartTimer() + { + isRunning = true; + Debug.Log($"TaskTimer: Timer started for {taskDuration} seconds"); + } + + public void PauseTimer() + { + isRunning = false; + Debug.Log("TaskTimer: Timer paused"); + } + + public void ResumeTimer() + { + isRunning = true; + Debug.Log("TaskTimer: Timer resumed"); + } + + public void ResetTimer() + { + timeRemaining = taskDuration; + UpdateTimerDisplay(); + Debug.Log("TaskTimer: Timer reset"); + } + + public void AddTime(float seconds) + { + timeRemaining += seconds; + Debug.Log($"TaskTimer: Added {seconds} seconds. New time: {timeRemaining}"); + } + + private void UpdateTimerDisplay() + { + string timeText = FormatTime(timeRemaining); + + // Update TextMeshPro + if (timerTextTMP != null) + { + timerTextTMP.text = timeText; + timerTextTMP.color = timeRemaining <= warningThreshold ? warningColor : normalColor; + } + + // Update Legacy Text + if (timerTextLegacy != null) + { + timerTextLegacy.text = timeText; + timerTextLegacy.color = timeRemaining <= warningThreshold ? warningColor : normalColor; + } + } + + private string FormatTime(float time) + { + int hours = Mathf.FloorToInt(time / 3600f); + int minutes = Mathf.FloorToInt((time % 3600f) / 60f); + int seconds = Mathf.FloorToInt(time % 60f); + + if (showHours) + { + return string.Format("{0:00}:{1:00}:{2:00}", hours, minutes, seconds); + } + else + { + int totalMinutes = Mathf.FloorToInt(time / 60f); + return string.Format("{0:00}:{1:00}", totalMinutes, seconds); + } + } + + private void OnTimerExpired() + { + isRunning = false; + Debug.Log("TaskTimer: Time expired! Returning to Lobby..."); + + // Load Lobby scene + SceneManager.LoadScene("Lobby"); + } + + // Public methods for external control + public float GetTimeRemaining() + { + return timeRemaining; + } + + public bool IsRunning() + { + return isRunning; + } + + public float GetProgress() + { + return 1f - (timeRemaining / taskDuration); + } +} + diff --git a/Unity/Assets/Scripts/TaskTimer.cs.meta b/Unity/Assets/Scripts/TaskTimer.cs.meta new file mode 100644 index 0000000..de87efa --- /dev/null +++ b/Unity/Assets/Scripts/TaskTimer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 50a2ca0ac07ab3f40b2ffe147eb4bc90 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: