Files
Virtual-Tutor/Unity/Assets/Scripts/ARVRMenu.cs

236 lines
7.4 KiB
C#

using UnityEngine;
using UnityEngine.SceneManagement;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class TaskButtonManager : MonoBehaviour
{
[Header("UDP Settings")]
[SerializeField] private int udpPort = 5555;
[SerializeField] private bool enableUDPControl = true;
private UdpClient udpClient;
private Thread udpListenerThread;
private bool isListening = false;
private string pendingSceneName = null;
private string pendingTimerCommand = null;
private readonly object sceneLock = new object();
private readonly object timerLock = new object();
private readonly object notesLock = new object();
private TaskTimer taskTimer;
private NotesDisplay notesDisplay;
private string pendingNotesText = null;
private void Start()
{
// Find TaskTimer in the scene
taskTimer = FindObjectOfType<TaskTimer>();
// Find NotesDisplay in the scene
notesDisplay = FindObjectOfType<NotesDisplay>();
if (enableUDPControl)
{
StartUDPListener();
}
}
private void Update()
{
// Check for pending UDP scene changes (must be done on main thread)
lock (sceneLock)
{
if (!string.IsNullOrEmpty(pendingSceneName))
{
LoadSceneByName(pendingSceneName);
pendingSceneName = null;
}
}
// Check for pending timer commands (must be done on main thread)
lock (timerLock)
{
if (!string.IsNullOrEmpty(pendingTimerCommand))
{
if (taskTimer != null)
{
taskTimer.ProcessTimerCommand(pendingTimerCommand);
}
else
{
Debug.LogWarning("TaskTimer not found in scene. Cannot process timer command.");
}
pendingTimerCommand = null;
}
}
// Check for pending notes updates (must be done on main thread)
lock (notesLock)
{
if (!string.IsNullOrEmpty(pendingNotesText))
{
if (notesDisplay != null)
{
notesDisplay.SetNotes(pendingNotesText);
}
else
{
Debug.LogWarning("NotesDisplay not found in scene. Cannot display notes text.");
}
pendingNotesText = null;
}
}
// VR Tasks (Keys 1-4)
if (Input.GetKeyDown(KeyCode.Alpha1) || Input.GetKeyDown(KeyCode.Keypad1))
LoadSceneByName("VR-Task1");
else if (Input.GetKeyDown(KeyCode.Alpha2) || Input.GetKeyDown(KeyCode.Keypad2))
LoadSceneByName("VR -Task2");
else if (Input.GetKeyDown(KeyCode.Alpha3) || Input.GetKeyDown(KeyCode.Keypad3))
LoadSceneByName("VR -Task3");
else if (Input.GetKeyDown(KeyCode.Alpha4) || Input.GetKeyDown(KeyCode.Keypad4))
LoadSceneByName("VR -Task4");
// AR Tasks (Keys 5-8)
else if (Input.GetKeyDown(KeyCode.Alpha5) || Input.GetKeyDown(KeyCode.Keypad5))
LoadSceneByName("AR-Task1");
else if (Input.GetKeyDown(KeyCode.Alpha6) || Input.GetKeyDown(KeyCode.Keypad6))
LoadSceneByName("AR-Task2");
else if (Input.GetKeyDown(KeyCode.Alpha7) || Input.GetKeyDown(KeyCode.Keypad7))
LoadSceneByName("AR-Task3");
else if (Input.GetKeyDown(KeyCode.Alpha8) || Input.GetKeyDown(KeyCode.Keypad8))
LoadSceneByName("AR-Task4");
// Lobby (Key L or 0)
else if (Input.GetKeyDown(KeyCode.L) || Input.GetKeyDown(KeyCode.Alpha0) || Input.GetKeyDown(KeyCode.Keypad0))
LoadSceneByName("Lobby");
}
private void StartUDPListener()
{
try
{
isListening = true;
udpClient = new UdpClient(udpPort);
udpListenerThread = new Thread(new ThreadStart(ListenForUDPCommands));
udpListenerThread.IsBackground = true;
udpListenerThread.Start();
Debug.Log($"UDP Listener started on port {udpPort}");
}
catch (System.Exception e)
{
Debug.LogError($"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($"UDP receive error: {e.Message}");
}
}
}
}
private void ProcessUDPCommand(string message)
{
Debug.Log($"Received UDP command: {message}");
if (string.IsNullOrEmpty(message))
return;
// Parse command format: COMMAND:Parameter (Parameter may contain additional colons)
int separatorIndex = message.IndexOf(':');
if (separatorIndex > 0 && separatorIndex < message.Length - 1)
{
string commandType = message.Substring(0, separatorIndex).Trim().ToUpper();
string parameter = message.Substring(separatorIndex + 1); // keep raw to preserve spaces/colons
if (commandType == "SWITCH")
{
// Scene switching command
lock (sceneLock)
{
pendingSceneName = parameter;
}
Debug.Log($"Scheduled scene switch to: {parameter}");
}
else if (commandType == "TIMER")
{
// Timer control command
lock (timerLock)
{
pendingTimerCommand = parameter;
}
Debug.Log($"Scheduled timer command: {parameter}");
}
else if (commandType == "NOTES")
{
// Notes display command
lock (notesLock)
{
pendingNotesText = parameter;
}
Debug.Log($"Scheduled notes update: {parameter}");
}
else
{
Debug.LogWarning($"Unknown UDP command type: {commandType}. Expected: SWITCH, TIMER or NOTES");
}
}
else
{
Debug.LogWarning($"Invalid UDP command format: {message}. Expected format: COMMAND:Parameter (e.g., SWITCH:SceneName, TIMER:START or NOTES:Your text)");
}
}
private void LoadSceneByName(string sceneName)
{
Debug.Log($"Loading scene: {sceneName}");
SceneManager.LoadScene(sceneName);
}
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("UDP Listener stopped");
}
}