data_transfer
další minihra - chybí desing
This commit is contained in:
8
Assets/Scripts/data_transfer.meta
Normal file
8
Assets/Scripts/data_transfer.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f58705c1c4d76414abdfecdd1db84138
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
204
Assets/Scripts/data_transfer/Data_transfer.cs
Normal file
204
Assets/Scripts/data_transfer/Data_transfer.cs
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
public class GPSTaskManager : MonoBehaviour, ITask
|
||||||
|
{
|
||||||
|
[Header("Target Location")]
|
||||||
|
[SerializeField] private double targetLatitude = 48.8584;
|
||||||
|
[SerializeField] private double targetLongitude = 2.2945;
|
||||||
|
|
||||||
|
[Header("Task Settings")]
|
||||||
|
[SerializeField] private float completionRadius = 15f;
|
||||||
|
[SerializeField] private float updateInterval = 1f;
|
||||||
|
|
||||||
|
[Header("GPS Initialization")]
|
||||||
|
[SerializeField] private float gpsInitTimeout = 20f;
|
||||||
|
[SerializeField] private float desiredAccuracyMeters = 5f;
|
||||||
|
[SerializeField] private float updateDistanceMeters = 1f;
|
||||||
|
|
||||||
|
[Header("UI References")]
|
||||||
|
[SerializeField] private TMP_Text distanceText;
|
||||||
|
[SerializeField] private TMP_Text bearingText;
|
||||||
|
[SerializeField] private TMP_Text statusText;
|
||||||
|
|
||||||
|
public event Action OnTaskCompleted;
|
||||||
|
public event Action<float, float> OnLocationUpdated;
|
||||||
|
|
||||||
|
private Action<ITask> _onCompleted;
|
||||||
|
private Action<ITask> _onExit;
|
||||||
|
|
||||||
|
public string TaskID { get; set; }
|
||||||
|
public TaskType TaskType { get; set; }
|
||||||
|
public string TaskName { get; set; }
|
||||||
|
public (double, double) TaskLocation { get; set; }
|
||||||
|
public bool IsCompleted { get; private set; }
|
||||||
|
|
||||||
|
private bool _gpsInitialized = false;
|
||||||
|
private bool _taskCompleted = false;
|
||||||
|
private bool _isRunning = false;
|
||||||
|
private Coroutine _trackingCoroutine;
|
||||||
|
|
||||||
|
private const double EarthRadiusMeters = 6_371_000.0;
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
SetStatus("Initializing GPS…");
|
||||||
|
_trackingCoroutine = StartCoroutine(InitializeAndTrack());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
StopTracking();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTarget(double latitude, double longitude)
|
||||||
|
{
|
||||||
|
targetLatitude = latitude;
|
||||||
|
targetLongitude = longitude;
|
||||||
|
_taskCompleted = false;
|
||||||
|
IsCompleted = false;
|
||||||
|
Debug.Log($"[GPS] New target → ({latitude:F6}, {longitude:F6})");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StopTracking()
|
||||||
|
{
|
||||||
|
_isRunning = false;
|
||||||
|
if (_trackingCoroutine != null)
|
||||||
|
{
|
||||||
|
StopCoroutine(_trackingCoroutine);
|
||||||
|
_trackingCoroutine = null;
|
||||||
|
}
|
||||||
|
Input.location.Stop();
|
||||||
|
Debug.Log("[GPS] Tracking stopped.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Initialize(Action<ITask> onCompleted)
|
||||||
|
{
|
||||||
|
_onCompleted = onCompleted;
|
||||||
|
IsCompleted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Complete()
|
||||||
|
{
|
||||||
|
if (IsCompleted) return;
|
||||||
|
|
||||||
|
IsCompleted = true;
|
||||||
|
_onCompleted?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ExitTask(Action<ITask> onExit)
|
||||||
|
{
|
||||||
|
_onExit = onExit;
|
||||||
|
_onExit?.Invoke(this);
|
||||||
|
|
||||||
|
StopTracking();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IEnumerator InitializeAndTrack()
|
||||||
|
{
|
||||||
|
if (!Input.location.isEnabledByUser)
|
||||||
|
{
|
||||||
|
SetStatus("ERROR: GPS disabled.");
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input.location.Start(desiredAccuracyMeters, updateDistanceMeters);
|
||||||
|
SetStatus("Starting GPS…");
|
||||||
|
|
||||||
|
float elapsed = 0f;
|
||||||
|
while (Input.location.status == LocationServiceStatus.Initializing && elapsed < gpsInitTimeout)
|
||||||
|
{
|
||||||
|
elapsed += 0.5f;
|
||||||
|
yield return new WaitForSeconds(0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input.location.status != LocationServiceStatus.Running)
|
||||||
|
{
|
||||||
|
SetStatus("ERROR: GPS failed.");
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_gpsInitialized = true;
|
||||||
|
_isRunning = true;
|
||||||
|
SetStatus("GPS Active ✓");
|
||||||
|
|
||||||
|
while (_isRunning)
|
||||||
|
{
|
||||||
|
LocationInfo loc = Input.location.lastData;
|
||||||
|
|
||||||
|
float distance = CalculateDistance(loc.latitude, loc.longitude,
|
||||||
|
targetLatitude, targetLongitude);
|
||||||
|
|
||||||
|
float bearing = CalculateBearing(loc.latitude, loc.longitude,
|
||||||
|
targetLatitude, targetLongitude);
|
||||||
|
|
||||||
|
UpdateUI(distance, bearing);
|
||||||
|
OnLocationUpdated?.Invoke(distance, bearing);
|
||||||
|
|
||||||
|
if (!_taskCompleted && distance <= completionRadius)
|
||||||
|
{
|
||||||
|
_taskCompleted = true;
|
||||||
|
HandleTaskCompleted(distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(updateInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleTaskCompleted(float finalDistance)
|
||||||
|
{
|
||||||
|
Debug.Log($"[GPS] TASK COMPLETED ({finalDistance:F1}m)");
|
||||||
|
SetStatus($" Done ({finalDistance:F1}m)");
|
||||||
|
|
||||||
|
OnTaskCompleted?.Invoke();
|
||||||
|
|
||||||
|
Complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateDistance(double lat1, double lon1, double lat2, double lon2)
|
||||||
|
{
|
||||||
|
double dLat = ToRadians(lat2 - lat1);
|
||||||
|
double dLon = ToRadians(lon2 - lon1);
|
||||||
|
|
||||||
|
double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
|
||||||
|
Math.Cos(ToRadians(lat1)) * Math.Cos(ToRadians(lat2)) *
|
||||||
|
Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
|
||||||
|
|
||||||
|
double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
|
||||||
|
return (float)(EarthRadiusMeters * c);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateBearing(double lat1, double lon1, double lat2, double lon2)
|
||||||
|
{
|
||||||
|
double dLon = ToRadians(lon2 - lon1);
|
||||||
|
|
||||||
|
double y = Math.Sin(dLon) * Math.Cos(ToRadians(lat2));
|
||||||
|
double x = Math.Cos(ToRadians(lat1)) * Math.Sin(ToRadians(lat2)) -
|
||||||
|
Math.Sin(ToRadians(lat1)) * Math.Cos(ToRadians(lat2)) * Math.Cos(dLon);
|
||||||
|
|
||||||
|
double brng = ToDegrees(Math.Atan2(y, x));
|
||||||
|
return (float)((brng + 360) % 360);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateUI(float distance, float bearing)
|
||||||
|
{
|
||||||
|
if (distanceText != null)
|
||||||
|
distanceText.text = $"Distance: {distance:F1} m";
|
||||||
|
|
||||||
|
if (bearingText != null)
|
||||||
|
bearingText.text = $"Bearing: {bearing:F1}°";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetStatus(string message)
|
||||||
|
{
|
||||||
|
if (statusText != null)
|
||||||
|
statusText.text = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double ToRadians(double deg) => deg * Math.PI / 180.0;
|
||||||
|
private static double ToDegrees(double rad) => rad * 180.0 / Math.PI;
|
||||||
|
}
|
||||||
2
Assets/Scripts/data_transfer/Data_transfer.cs.meta
Normal file
2
Assets/Scripts/data_transfer/Data_transfer.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a3ce561d9b4708f40855570fb194929d
|
||||||
Reference in New Issue
Block a user