Added UDP control functionality to TaskTimer, allowing timer commands via UDP. Updated README to include new timer commands: START, PAUSE, RESUME, and RESET.

This commit is contained in:
tom.hempel
2025-10-21 18:17:41 +02:00
parent ae12616a5f
commit 8274e78d1b
2 changed files with 156 additions and 1 deletions

View File

@ -2,6 +2,10 @@ using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using TMPro;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class TaskTimer : MonoBehaviour
{
@ -15,6 +19,12 @@ public class TaskTimer : MonoBehaviour
[Tooltip("Show warning when time is low (in seconds)")]
public float warningThreshold = 30f;
[Header("UDP Control Settings")]
[SerializeField] private int udpPort = 5555;
[SerializeField] private bool enableUDPControl = true;
[Tooltip("If enabled, timer will only start via UDP command (ignores autoStart)")]
[SerializeField] private bool waitForUDPStart = false;
[Header("UI References")]
[Tooltip("TextMeshPro component to display timer (recommended for VR)")]
public TextMeshProUGUI timerTextTMP;
@ -35,11 +45,24 @@ public class TaskTimer : MonoBehaviour
private float timeRemaining;
private bool isRunning;
// UDP infrastructure
private UdpClient udpClient;
private Thread udpListenerThread;
private bool isListening = false;
private string pendingCommand = null;
private readonly object commandLock = new object();
private void Start()
{
timeRemaining = taskDuration;
if (autoStart)
if (enableUDPControl)
{
StartUDPListener();
}
// Only auto-start if not waiting for UDP command
if (autoStart && !waitForUDPStart)
{
StartTimer();
}
@ -49,6 +72,16 @@ public class TaskTimer : MonoBehaviour
private void Update()
{
// Check for pending UDP commands (must be done on main thread)
lock (commandLock)
{
if (!string.IsNullOrEmpty(pendingCommand))
{
ProcessTimerCommand(pendingCommand);
pendingCommand = null;
}
}
if (!isRunning)
return;
@ -155,5 +188,120 @@ public class TaskTimer : MonoBehaviour
{
return 1f - (timeRemaining / taskDuration);
}
// UDP Control Methods
private void StartUDPListener()
{
try
{
isListening = true;
udpClient = new UdpClient(udpPort);
udpListenerThread = new Thread(new ThreadStart(ListenForUDPCommands));
udpListenerThread.IsBackground = true;
udpListenerThread.Start();
Debug.Log($"TaskTimer: UDP Listener started on port {udpPort}");
}
catch (System.Exception e)
{
Debug.LogError($"TaskTimer: Failed to start UDP listener: {e.Message}");
}
}
private void ListenForUDPCommands()
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, udpPort);
while (isListening)
{
try
{
byte[] data = udpClient.Receive(ref remoteEndPoint);
string message = Encoding.UTF8.GetString(data);
ProcessUDPCommand(message);
}
catch (System.Exception e)
{
if (isListening)
{
Debug.LogError($"TaskTimer: UDP receive error: {e.Message}");
}
}
}
}
private void ProcessUDPCommand(string message)
{
Debug.Log($"TaskTimer: Received UDP command: {message}");
if (string.IsNullOrEmpty(message))
return;
// Parse command format: TIMER:COMMAND (e.g., TIMER:START, TIMER:PAUSE, TIMER:RESET, TIMER:RESUME)
string[] parts = message.Split(':');
if (parts.Length == 2 && parts[0].Trim().ToUpper() == "TIMER")
{
string command = parts[1].Trim().ToUpper();
lock (commandLock)
{
pendingCommand = command;
}
Debug.Log($"TaskTimer: Scheduled command: {command}");
}
else
{
Debug.LogWarning($"TaskTimer: Invalid UDP command format: {message}. Expected format: TIMER:COMMAND (e.g., TIMER:START)");
}
}
private void ProcessTimerCommand(string command)
{
switch (command)
{
case "START":
StartTimer();
break;
case "PAUSE":
PauseTimer();
break;
case "RESUME":
ResumeTimer();
break;
case "RESET":
ResetTimer();
break;
default:
Debug.LogWarning($"TaskTimer: Unknown command: {command}. Valid commands: START, PAUSE, RESUME, RESET");
break;
}
}
private void OnDestroy()
{
StopUDPListener();
}
private void OnApplicationQuit()
{
StopUDPListener();
}
private void StopUDPListener()
{
isListening = false;
if (udpClient != null)
{
udpClient.Close();
udpClient = null;
}
if (udpListenerThread != null && udpListenerThread.IsAlive)
{
udpListenerThread.Abort();
udpListenerThread = null;
}
Debug.Log("TaskTimer: UDP Listener stopped");
}
}