data_transfer

další minihra - chybí desing
This commit is contained in:
2026-03-28 10:59:23 +01:00
parent 72a75c121a
commit 6a7314ff4e
3 changed files with 214 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f58705c1c4d76414abdfecdd1db84138
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a3ce561d9b4708f40855570fb194929d