diff --git a/Assets/Scenes/Testing MQTT.unity b/Assets/Scenes/Testing MQTT.unity index 24dd6a8..92a9820 100644 --- a/Assets/Scenes/Testing MQTT.unity +++ b/Assets/Scenes/Testing MQTT.unity @@ -382,6 +382,7 @@ GameObject: m_Component: - component: {fileID: 649525403} - component: {fileID: 649525404} + - component: {fileID: 649525405} m_Layer: 0 m_Name: GameManager m_TagString: Untagged @@ -416,9 +417,25 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 9814a729a72ea7245aee98f3c0831d15, type: 3} m_Name: m_EditorClassIdentifier: - startCanvas: {fileID: 360865754} - movementScript: {fileID: 512796979} - lookScript: {fileID: 875671707} + startUI: {fileID: 360865754} + playerMove: {fileID: 512796979} + mouseLook: {fileID: 875671707} + mqttCollector: {fileID: 649525405} +--- !u!114 &649525405 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 649525402} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d97d018fed6c13e4d825d7e154421c63, type: 3} + m_Name: + m_EditorClassIdentifier: + brokerIp: 127.0.0.1 + port: 1883 + topic: sensor/heartrate --- !u!1 &875671702 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index fdf1f59..3a9163c 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -4,40 +4,56 @@ using UnityEngine.InputSystem.Utilities; public class GameManager : MonoBehaviour { - [Header("UI do ukrycia")] - public GameObject startCanvas; + [Header("Interfejs")] + public GameObject startUI; // Twój Canvas z napisem - [Header("Komponenty gracza")] - public PlayerMove movementScript; - public MouseLook lookScript; + [Header("Skrypty Gracza")] + public PlayerMove playerMove; // Skrypt poruszania fasolką + public MouseLook mouseLook; // Skrypt obracania kamerą - // public MqttCollector mqttScript; // Odkomentujesz to później + [Header("Moduł MQTT")] + public MqttCollector mqttCollector; // Skrypt MQTTnet private bool hasStarted = false; void Start() { - // Blokada na starcie - if (movementScript != null) movementScript.enabled = false; - if (lookScript != null) lookScript.canLook = false; + // 1. Upewnij się, że na starcie wszystko jest zablokowane + if (playerMove != null) playerMove.enabled = false; + if (mouseLook != null) mouseLook.canLook = false; + // 2. Kursor musi być widoczny i wolny, żeby gracz wiedział, że gra jeszcze nie ruszyła Cursor.lockState = CursorLockMode.None; Cursor.visible = true; - // Czekamy na dowolny klawisz - InputSystem.onAnyButtonPress.CallOnce(ctrl => Begin()); + // 3. Czekamy na "Any Key" (dowolny przycisk klawiatury, myszy lub kontrolera VR) + InputSystem.onAnyButtonPress.CallOnce(ctrl => StartGame()); + + Debug.Log("GameManager: Oczekiwanie na start..."); } - void Begin() + void StartGame() { if (hasStarted) return; hasStarted = true; - if (startCanvas != null) startCanvas.SetActive(false); - if (movementScript != null) movementScript.enabled = true; - if (lookScript != null) lookScript.EnableLooking(); + // 1. Ukrywamy UI + if (startUI != null) + startUI.SetActive(false); - // if (mqttScript != null) mqttScript.BeginSession(); - Debug.Log("Gra wystartowała!"); + // 2. Odblokowujemy ruch i kamerę + if (playerMove != null) + playerMove.enabled = true; + + if (mouseLook != null) + mouseLook.EnableLooking(); // Ta funkcja schowa też kursor + + // 3. Odpalamy zbieranie danych MQTT + if (mqttCollector != null) + { + mqttCollector.BeginSession(); + } + + Debug.Log("SYSTEM: Gra i logowanie danych uruchomione!"); } } \ No newline at end of file diff --git a/Assets/Scripts/HearthRateData.cs b/Assets/Scripts/HearthRateData.cs new file mode 100644 index 0000000..323e948 --- /dev/null +++ b/Assets/Scripts/HearthRateData.cs @@ -0,0 +1,8 @@ +using System; + +[Serializable] +public class HeartRateData +{ + // Jeśli serwer wysyła {"hr": 70}, to musi być 'hr' + public int hr; +} \ No newline at end of file diff --git a/Assets/Scripts/HearthRateData.cs.meta b/Assets/Scripts/HearthRateData.cs.meta new file mode 100644 index 0000000..6e88c04 --- /dev/null +++ b/Assets/Scripts/HearthRateData.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1c96e46d44abafb408a15a62a85febe7 \ No newline at end of file diff --git a/Assets/Scripts/MqttCollector.cs b/Assets/Scripts/MqttCollector.cs new file mode 100644 index 0000000..c19d83f --- /dev/null +++ b/Assets/Scripts/MqttCollector.cs @@ -0,0 +1,89 @@ +using UnityEngine; +using MQTTnet; +using MQTTnet.Client; +using System; +using System.Text; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +public class MqttCollector : MonoBehaviour +{ + private IMqttClient _mqttClient; + private string _csvPath; + + [Header("Ustawienia MQTT")] + public string brokerIp = "127.0.0.1"; + public int port = 1883; + public string topic = "sensor/heartrate"; + + // Funkcja wywoływana przez GameManager + public async void BeginSession() + { + // 1. Stworzenie pliku CSV w folderze projektu + string folder = Application.persistentDataPath + "/Sesje_Badawcze/"; + if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); + + _csvPath = folder + "Dane_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".csv"; + File.WriteAllText(_csvPath, "Timestamp;Godzina;Tetno\n"); + + Debug.Log($"MQTT: Plik zapisu: {_csvPath}"); + + // 2. Konfiguracja MQTTnet + var factory = new MqttFactory(); + _mqttClient = factory.CreateMqttClient(); + + var options = new MqttClientOptionsBuilder() + .WithTcpServer(brokerIp, port) + .Build(); + + // 3. Reakcja na odebraną wiadomość + _mqttClient.ApplicationMessageReceivedAsync += e => + { + string payload = Encoding.UTF8.GetString(e.ApplicationMessage.PayloadSegment); + SaveData(payload); + return Task.CompletedTask; + }; + + // 4. Połączenie asynchroniczne + try + { + await _mqttClient.ConnectAsync(options, CancellationToken.None); + + var subOptions = new MqttClientSubscribeOptionsBuilder() + .WithTopicFilter(topic) + .Build(); + + await _mqttClient.SubscribeAsync(subOptions, CancellationToken.None); + Debug.Log("MQTT: Połączono i słucham tętna!"); + } + catch (Exception ex) + { + Debug.LogError($"MQTT Connection Error: {ex.Message}"); + } + } + + private void SaveData(string json) + { + try + { + HeartRateData data = JsonUtility.FromJson(json); + + // Format: Data i czas ; tętno + string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + string line = $"{timestamp};{data.hr}\n"; + + File.AppendAllText(_csvPath, line); + Debug.Log($"Zapisano HR: {data.hr}"); + } + catch (Exception ex) + { + Debug.LogWarning($"Błąd parsowania: {json}. Szczegóły: {ex.Message}"); + } + } + + private async void OnApplicationQuit() + { + if (_mqttClient != null) await _mqttClient.DisconnectAsync(); + } +} \ No newline at end of file diff --git a/Assets/Scripts/MqttCollector.cs.meta b/Assets/Scripts/MqttCollector.cs.meta new file mode 100644 index 0000000..b7894c5 --- /dev/null +++ b/Assets/Scripts/MqttCollector.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d97d018fed6c13e4d825d7e154421c63 \ No newline at end of file