From be595da357301d02528454803b149fbf1527c112 Mon Sep 17 00:00:00 2001 From: trubkokrtek Date: Sat, 21 Mar 2026 22:40:20 +0100 Subject: [PATCH 1/2] Added test mode and manual positioning --- Assets/ClientSDK/Protocol.cs | 61 ++--- Assets/GameManager/GameManager.cs | 40 +++- Assets/GameManager/GameManager_Input.cs | 154 ++++++++++++ Assets/GameManager/GameManager_Input.cs.meta | 2 + Assets/GameManager/GameManager_Map.cs | 58 ++--- Assets/GameManager/GameManager_Network.cs | 5 +- Assets/Scenes/Client.unity | 234 ++++++++++++++++++- 7 files changed, 481 insertions(+), 73 deletions(-) create mode 100644 Assets/GameManager/GameManager_Input.cs create mode 100644 Assets/GameManager/GameManager_Input.cs.meta diff --git a/Assets/ClientSDK/Protocol.cs b/Assets/ClientSDK/Protocol.cs index f6d4d04..e867ad5 100644 --- a/Assets/ClientSDK/Protocol.cs +++ b/Assets/ClientSDK/Protocol.cs @@ -9,38 +9,39 @@ namespace GeoSus.Client { #region Základní typy -public struct Position -{ - [JsonProperty("lat")] - public double Lat { get; set; } - - [JsonProperty("lon")] - public double Lon { get; set; } - - public Position(double lat, double lon) + public struct Position { - Lat = lat; - Lon = lon; - } - - // Haversine vzdálenost v metrech - public double DistanceTo(Position other) - { - const double R = 6371000; - var lat1 = Lat * Math.PI / 180; - var lat2 = other.Lat * Math.PI / 180; - var dLat = (other.Lat - Lat) * Math.PI / 180; - var dLon = (other.Lon - Lon) * Math.PI / 180; - - var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + - Math.Cos(lat1) * Math.Cos(lat2) * - Math.Sin(dLon / 2) * Math.Sin(dLon / 2); - var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); - - return R * c; - } -} + [JsonProperty("lat")] + public double Lat { get; set; } + [JsonProperty("lon")] + public double Lon { get; set; } + + public Position(double lat, double lon) + { + Lat = lat; + Lon = lon; + } + + // Haversine vzdálenost v metrech + public double DistanceTo(Position other) + { + const double R = 6371000; + var lat1 = Lat * Math.PI / 180; + var lat2 = other.Lat * Math.PI / 180; + var dLat = (other.Lat - Lat) * Math.PI / 180; + var dLon = (other.Lon - Lon) * Math.PI / 180; + + var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + + Math.Cos(lat1) * Math.Cos(lat2) * + Math.Sin(dLon / 2) * Math.Sin(dLon / 2); + var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); + + return R * c; + } + public static bool operator ==(Position left, Position right) { if (left.Lat == right.Lat && left.Lon == right.Lon) { return true; } else { return false; } } + public static bool operator !=(Position left, Position right) { return !(left == right); } + } [JsonConverter(typeof(StringEnumConverter))] public enum PlayerRole { Crew, Impostor } diff --git a/Assets/GameManager/GameManager.cs b/Assets/GameManager/GameManager.cs index 09d9633..62850eb 100644 --- a/Assets/GameManager/GameManager.cs +++ b/Assets/GameManager/GameManager.cs @@ -22,6 +22,7 @@ public class GameManager : MonoBehaviour protected GameManager_Network networkSubsystem; protected GameManager_UI uiSubsystem; protected GameManager_Map mapSubsystem; + protected GameManager_Input inputSubsystem; protected GameClient gameClient; @@ -41,18 +42,39 @@ public class GameManager : MonoBehaviour public PathwaySettings pathwaySettings; public AreaSettings areaSettings; + [Header("GPS")] + public GameObject Player; + + [Header("Debug")] + public bool testMode = false; + private GameClient _secondClient; + private GameClient _thirdClient; + private GameManager_Network _secondNetwork; + private GameManager_Network _thirdNetwork; + void Start() { DontDestroyOnLoad(this); if (displayName == null || displayName == "") { - displayName = "Player_" + UnityEngine.Random.Range(1000, 9999).ToString(); + displayName = GenerateUsername(); } - gameClient = new GameClient(GenerateUUID(), /*displayName*/ GenerateUsername()); + if (testMode) + { + _secondClient = new GameClient(GenerateUUID(), GenerateUsername()); + _secondNetwork = new GameManager_Network(_secondClient); + _thirdClient = new GameClient(GenerateUUID(), GenerateUsername()); + _thirdNetwork = new GameManager_Network(_thirdClient); + + _secondNetwork.OpenConection(); + _thirdNetwork.OpenConection(); + } + gameClient = new GameClient(GenerateUUID(), displayName); uiSubsystem = new GameManager_UI(gameClient, JoinCreateLobby, InLobby, LoadingScreen, GameScreen); networkSubsystem = new GameManager_Network(gameClient); mapSubsystem = new GameManager_Map(gameClient, MapCenterPoint, buildingSettings, pathwaySettings, areaSettings); + inputSubsystem = new GameManager_Input(gameClient, Player, testMode); networkSubsystem.OpenConection(); } private void Update() @@ -70,7 +92,7 @@ public class GameManager : MonoBehaviour } } catch (NullReferenceException ex) { } - + inputSubsystem.positionCheck(); } @@ -89,6 +111,10 @@ public class GameManager : MonoBehaviour public void CreateLobbyButton() { networkSubsystem.CrateLobby(50.7727264, 15.0719876); + if (testMode) + { + StartCoroutine(ConnectTestClients()); + } } public void JoinLobbyButton() { @@ -113,5 +139,13 @@ public class GameManager : MonoBehaviour void OnApplicationQuit() { gameClient.Disconnect(); + _secondClient?.Disconnect(); + _thirdClient?.Disconnect(); + } + IEnumerator ConnectTestClients() + { + yield return new WaitForSeconds(2f); + _secondNetwork.JoinLobby(gameClient.CurrentLobbyState.JoinCode); + _thirdNetwork.JoinLobby(gameClient.CurrentLobbyState.JoinCode); } } diff --git a/Assets/GameManager/GameManager_Input.cs b/Assets/GameManager/GameManager_Input.cs new file mode 100644 index 0000000..2c42f6f --- /dev/null +++ b/Assets/GameManager/GameManager_Input.cs @@ -0,0 +1,154 @@ +using UnityEngine; +using GeoSus.Client; +using System; +namespace Subsystems +{ + public static class PositonExtensions + { + public static Position ToLocal(this Position position, Position center) + { + double latDiff = position.Lat - center.Lat; + double lonDiff = position.Lon - center.Lon; + double metersPerDegreeLat = 111320.0; + double metersPerDegreeLon = 111320.0 * Math.Cos(center.Lat * Math.PI / 180.0); + float x = (float)(lonDiff * metersPerDegreeLon); + float z = (float)(latDiff * metersPerDegreeLat); + return new Position(z, x); + } + public static Vector3 ToLocalVector3(this Position position, Position center) + { + return position.ToLocal(center).ToVector3(); //TODO: Implementace v subsystemech + } + public static Vector3 ToVector3(this Position position) + { + return new Vector3((float)position.Lon, 0, (float)position.Lat); //TODO: Implementace v subsystemech + } + public static double DistanceTo(this Vector3 pos, Vector3 other) + { + return Math.Sqrt((other.x - pos.x) * (other.x - pos.x) + (other.z - pos.z) * (other.z - pos.z)); + } + + } + + public class GameManager_Input + { + private GameClient _gameClient; + private Position _currentPosition; + private Position _lastSentPosition; + private GameObject _player; + private bool _testMode; + private float _speed = 0.00001f; + private Position _mapCenter; + public GameManager_Input(GameClient gameClient, GameObject player, bool testMode) + { + _gameClient = gameClient; + _player = player; + _testMode = testMode; + } + public void positionCheck() + { + try + { + if (_gameClient.CurrentLobbyState.Phase == GamePhase.Playing) + { + if (_testMode) + { + + if (_currentPosition == null || _currentPosition == new Position(0,0)) + { + //Init blok + _currentPosition = _gameClient.CurrentLobbyState.MapData.Center; + _mapCenter = _gameClient.CurrentLobbyState.MapData.Center; + _lastSentPosition = _currentPosition; + } + + TestPlayerPosition(); + } + else + { + //TODO: Real GPS + } + } + } + catch (NullReferenceException ex) { Debug.Log(ex); } + } + private void TestPlayerPosition() + { + double x = Input.GetAxis("Horizontal"); + double y = Input.GetAxis("Vertical"); + Debug.Log($"Input: {x}, {y}"); + _currentPosition = new Position( _lastSentPosition.Lat + y * _speed, _lastSentPosition.Lon + x * _speed); + Debug.Log($"Current Position: {_currentPosition.Lat}, {_currentPosition.Lon}"); + var localCurrent = _currentPosition.ToLocalVector3(_mapCenter); + Debug.Log($"Local Current Position: {localCurrent}"); + var heading = CalculateHeading(_lastSentPosition.ToLocalVector3(_mapCenter), localCurrent); + if (heading != null) + { + Debug.Log($"Heading: {heading}"); + _player.transform.rotation = Quaternion.Euler(0, (float)heading, 0); + } + _player.transform.position = localCurrent; + try + { + if (_currentPosition != _lastSentPosition) + { + _gameClient.UpdatePosition(_currentPosition); + _lastSentPosition = _currentPosition; + } + } + catch + { + _gameClient.UpdatePosition(_currentPosition); + _lastSentPosition = _currentPosition; + } + } + private double? CalculateHeading(Vector3 first, Vector3 second) + { + double? heading = null; + if ((first - second).magnitude == 0) + { + return null; + } + else if (first.x == second.x && first.z < second.z) + { + return 0; + } + else if (first.x == second.x && first.z > second.z) + { + return 180; + } + else if (first.x > second.x && first.z == second.z) + { + return 270; + } + else if (first.x < second.x && first.z == second.z) + { + return 90; + } + else if (first.x < second.x && first.z < second.z) + { + heading = Math.Asin((second.z - first.z) / first.DistanceTo(second)); + return (heading * 180) / Math.PI; + } + else if (first.x < second.x && first.z > second.z) + { + heading = Math.Asin((second.z - first.z) / first.DistanceTo(second)); + return (heading * 180) / Math.PI + 180; + } + else if (first.x > second.x && first.z < second.z) + { + heading = Math.Asin((second.z - first.z) / first.DistanceTo(second)); + return (heading * 180) / Math.PI - 90; + } + else if (first.x > second.x && first.z > second.z) + { + heading = Math.Asin((second.z - first.z) / first.DistanceTo(second)); + return (heading * 180) / Math.PI - 90; + } + else + { + return heading; + } + } + } +} \ No newline at end of file diff --git a/Assets/GameManager/GameManager_Input.cs.meta b/Assets/GameManager/GameManager_Input.cs.meta new file mode 100644 index 0000000..04c61a4 --- /dev/null +++ b/Assets/GameManager/GameManager_Input.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 2ef1abfb1e85a7943925f9dc3cfea742 \ No newline at end of file diff --git a/Assets/GameManager/GameManager_Map.cs b/Assets/GameManager/GameManager_Map.cs index e78d616..30f9ce1 100644 --- a/Assets/GameManager/GameManager_Map.cs +++ b/Assets/GameManager/GameManager_Map.cs @@ -89,7 +89,12 @@ namespace Subsystems{ foreach (var building in _gameClient.CurrentLobbyState.MapData.GetBuildings()) { - var buildingType = _gameClient.CurrentLobbyState.MapData.BuildingTypes[_gameClient.CurrentLobbyState.MapData.GetBuildings().IndexOf(building)]; + string buildingType = "Unknown"; + try + { + buildingType = _gameClient.CurrentLobbyState.MapData.BuildingTypes[_gameClient.CurrentLobbyState.MapData.GetBuildings().IndexOf(building)]; + } + catch (Exception ex) { Debug.Log($"Error: {ex.Message}"); } building.Name = buildingType; GameObject b = BuildBuildingMesh(building); b.transform.parent = buildingsRoot.transform; @@ -106,6 +111,17 @@ namespace Subsystems{ } //TODO: POIs } + void ClearChildren() + { + List toDestroy = new List(); + foreach (Transform t in _mapCenterPoint.transform) + toDestroy.Add(t.gameObject); + foreach (var g in toDestroy) + { + UnityEngine.Object.DestroyImmediate(g); + } + } + #region Mesh Building GameObject BuildBuildingMesh(MapBuilding b) { var building = new GameObject($"Building_{b.Name ?? "Unknown"}"); @@ -210,7 +226,7 @@ namespace Subsystems{ line.positionCount = w.Points.Count; for (int i = 0; i < w.Points.Count; i++) { - Vector3 pos = LatLonToLocal(w.Points[i]); + Vector3 pos = w.Points[i].ToLocalVector3(_gameClient.CurrentLobbyState.MapData.Center); pos.y = 0.1f; // Mírně nad zemí line.SetPosition(i, pos); } @@ -261,44 +277,14 @@ namespace Subsystems{ return area; } //TODO: POIs - void ClearChildren() - { - List toDestroy = new List(); - foreach (Transform t in _mapCenterPoint.transform) - toDestroy.Add(t.gameObject); - foreach (var g in toDestroy) - { - UnityEngine.Object.DestroyImmediate(g); - } - } - Vector3 LatLonToLocal(Position position) - { - if (_gameClient.CurrentLobbyState.MapData == null) return Vector3.zero; - - // Výpočet vzdálenosti a směru od středu - // Zjednodušená verze - pro malé vzdálenosti je dost přesná - - double latDiff = position.Lat - _gameClient.CurrentLobbyState.MapData.Center.Lat; - double lonDiff = position.Lon - _gameClient.CurrentLobbyState.MapData.Center.Lon; - - // Převod stupňů na metry - // 1 stupeň latitude ≈ 111320 metrů - // 1 stupeň longitude závisí na latitude: 111320 * cos(latitude) - double metersPerDegreeLat = 111320.0; - double metersPerDegreeLon = 111320.0 * Math.Cos(_gameClient.CurrentLobbyState.MapData.Center.Lat * Math.PI / 180.0); - - float x = (float)(lonDiff * metersPerDegreeLon); - float z = (float)(latDiff * metersPerDegreeLat); - - return new Vector3(x, 0, z); - } + #endregion #region Polygon Utils private Vector3 CalculatePolygonCenter(List points) { Vector3 center = Vector3.zero; foreach (var point in points) { - center += LatLonToLocal(point); + center += point.ToLocalVector3(_gameClient.CurrentLobbyState.MapData.Center); } return center / points.Count; } @@ -314,7 +300,7 @@ namespace Subsystems{ for (int i = 0; i < vertexCount; i++) { - Vector3 pos = LatLonToLocal(outline[i]) - center; + Vector3 pos = outline[i].ToLocalVector3(_gameClient.CurrentLobbyState.MapData.Center) - center; vertices[i] = pos; // Spodní vertices[i + vertexCount] = pos + Vector3.up * height; // Horní } @@ -364,7 +350,7 @@ namespace Subsystems{ for (int i = 0; i < vertexCount; i++) { - vertices[i] = LatLonToLocal(outline[i]) - center; + vertices[i] = outline[i].ToLocalVector3(_gameClient.CurrentLobbyState.MapData.Center) - center; } // Triangulace - fan pattern diff --git a/Assets/GameManager/GameManager_Network.cs b/Assets/GameManager/GameManager_Network.cs index 17adc9d..8b12e3f 100644 --- a/Assets/GameManager/GameManager_Network.cs +++ b/Assets/GameManager/GameManager_Network.cs @@ -2,6 +2,9 @@ using GeoSus.Client; using System.Collections; using System.Threading.Tasks; using UnityEngine; +using System.Collections.Generic; +using Subsystems; +using System.Linq; namespace Subsystems { @@ -129,8 +132,6 @@ namespace Subsystems Debug.LogError("Failed to create lobby: " + message.Error); } } - - public void CrateLobby(double lat, double lon) { _gameClient.CreateLobby(new Position(lat, lon)); diff --git a/Assets/Scenes/Client.unity b/Assets/Scenes/Client.unity index 13ccd78..1a5acba 100644 --- a/Assets/Scenes/Client.unity +++ b/Assets/Scenes/Client.unity @@ -1066,6 +1066,119 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 714061467} m_CullTransparentMesh: 1 +--- !u!1 &751597273 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 751597274} + - component: {fileID: 751597277} + - component: {fileID: 751597276} + - component: {fileID: 751597275} + m_Layer: 0 + m_Name: Capsule + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &751597274 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 751597273} + serializedVersion: 2 + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 0, z: 1} + m_LocalScale: {x: 0.1, y: 1, z: 0.1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1161233725} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!136 &751597275 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 751597273} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &751597276 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 751597273} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &751597277 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 751597273} + m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} --- !u!1 &808348697 GameObject: m_ObjectHideFlags: 0 @@ -1556,12 +1669,126 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1010702369} serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} + m_LocalPosition: {x: 0, y: 290.6, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!1 &1161233721 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1161233725} + - component: {fileID: 1161233724} + - component: {fileID: 1161233723} + - component: {fileID: 1161233722} + m_Layer: 0 + m_Name: Player + m_TagString: Player + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!136 &1161233722 +CapsuleCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1161233721} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5 + m_Height: 2 + m_Direction: 1 + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1161233723 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1161233721} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_ForceMeshLod: -1 + m_MeshLodSelectionBias: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_GlobalIlluminationMeshLod: 0 + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1161233724 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1161233721} + m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1161233725 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1161233721} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0.5, z: 0} + m_LocalScale: {x: 10, y: 10, z: 10} + m_ConstrainProportionsScale: 1 + m_Children: + - {fileID: 751597274} + m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1222944786 GameObject: @@ -2053,6 +2280,8 @@ MonoBehaviour: GrassMat: {fileID: 2100000, guid: 5a46533bdf4003449bc9146ccef44e27, type: 2} WaterMat: {fileID: 2100000, guid: 5a46533bdf4003449bc9146ccef44e27, type: 2} DefaultMat: {fileID: 2100000, guid: 5a46533bdf4003449bc9146ccef44e27, type: 2} + Player: {fileID: 1161233721} + testMode: 1 --- !u!1 &1403738861 GameObject: m_ObjectHideFlags: 0 @@ -3201,3 +3430,4 @@ SceneRoots: - {fileID: 247614967} - {fileID: 1631266633} - {fileID: 216559630} + - {fileID: 1161233725} From b872b526329f6d954dc84ffade2a1daa1fc98ce4 Mon Sep 17 00:00:00 2001 From: trubkokrtek Date: Sat, 28 Mar 2026 10:59:01 +0100 Subject: [PATCH 2/2] Added gps and ITask update --- Assets/GameManager/GameManager.cs | 3 - Assets/GameManager/GameManager_Input.cs | 104 +++++++++++++++++- Assets/GameManager/ITask.cs | 8 +- .../UnityDefaultRuntimeTheme.tss.meta | 11 -- Packages/manifest.json | 2 +- Packages/packages-lock.json | 2 +- 6 files changed, 108 insertions(+), 22 deletions(-) delete mode 100644 Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss.meta diff --git a/Assets/GameManager/GameManager.cs b/Assets/GameManager/GameManager.cs index 62850eb..0e82c80 100644 --- a/Assets/GameManager/GameManager.cs +++ b/Assets/GameManager/GameManager.cs @@ -1,10 +1,7 @@ using UnityEngine; using GeoSus.Client; using Subsystems; -using System.Threading; -using System.Threading.Tasks; using System.Collections; -using System.Collections.Generic; using System; using TMPro; /* diff --git a/Assets/GameManager/GameManager_Input.cs b/Assets/GameManager/GameManager_Input.cs index 2c42f6f..af90aa1 100644 --- a/Assets/GameManager/GameManager_Input.cs +++ b/Assets/GameManager/GameManager_Input.cs @@ -1,8 +1,21 @@ using UnityEngine; using GeoSus.Client; using System; +using System.Collections; + namespace Subsystems { + internal class CoroutineHost : MonoBehaviour + { + public CoroutineHost() { } + } + internal enum GPSState + { + Uninitialized, + Initializing, + Running, + Failed + } public static class PositonExtensions { public static Position ToLocal(this Position position, Position center) @@ -37,8 +50,11 @@ namespace Subsystems private Position _lastSentPosition; private GameObject _player; private bool _testMode; + + private GPSState _GPSState = GPSState.Uninitialized; private float _speed = 0.00001f; private Position _mapCenter; + private CoroutineHost _coroutineHost = new CoroutineHost(); public GameManager_Input(GameClient gameClient, GameObject player, bool testMode) { _gameClient = gameClient; @@ -54,7 +70,7 @@ namespace Subsystems if (_testMode) { - if (_currentPosition == null || _currentPosition == new Position(0,0)) + if (_currentPosition == null || _currentPosition == new Position(0, 0)) { //Init blok _currentPosition = _gameClient.CurrentLobbyState.MapData.Center; @@ -66,7 +82,37 @@ namespace Subsystems } else { - //TODO: Real GPS + if (_GPSState == GPSState.Uninitialized) + { + _coroutineHost.StartCoroutine(InitiallizeGPS()); + return; + } + else if (_GPSState == GPSState.Initializing) + { + return; + } + else if (_GPSState == GPSState.Running) + { + try + { + if (_currentPosition != _lastSentPosition) + { + _gameClient.UpdatePosition(_currentPosition); + _lastSentPosition = _currentPosition; + _player.transform.position = _currentPosition.ToLocalVector3(_mapCenter); + _player.transform.rotation = Quaternion.Euler(0, (float)CalculateHeading(_lastSentPosition.ToLocalVector3(_mapCenter), _currentPosition.ToLocalVector3(_mapCenter)), 0); + } + } + catch (Exception ex) + { + Debug.Log(ex); + } + } + else + { + Debug.Log("GPS failed, trying again...");) + _GPSState = GPSState.Uninitialized; + } } } } @@ -150,5 +196,59 @@ namespace Subsystems return heading; } } + IEnumerator InitiallizeGPS() + { + _GPSState = GPSState.Initializing; + if (!Input.location.isEnabledByUser) + { + Debug.LogError("Location not enabled on device or app does not have permission to access location"); + } + // Starts the location service. + + float desiredAccuracyInMeters = 10f; + float updateDistanceInMeters = 10f; + + Input.location.Start(desiredAccuracyInMeters, updateDistanceInMeters); + + // Waits until the location service initializes + int maxWait = 20; + while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0) + { + yield return new WaitForSeconds(1); + maxWait--; + } + + // If the service didn't initialize in 20 seconds this cancels location service use. + if (maxWait < 1) + { + _GPSState = GPSState.Failed; + Debug.LogError("Timed out"); + yield break; + } + _GPSState = GPSState.Running; + yield return _coroutineHost.StartCoroutine(GPSService()); + } + IEnumerator GPSService() + { + // Check if the user has location service enabled. + + + // If the connection failed this cancels location service use. + if (Input.location.status == LocationServiceStatus.Failed) + { + Debug.LogError("Unable to determine device location"); + yield break; + } + else + { + // If the connection succeeded, this retrieves the device's current location and displays it in the Console window. + _currentPosition = new Position(Input.location.lastData.latitude, Input.location.lastData.longitude); + Debug.Log("Location: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude + " " + Input.location.lastData.altitude + " " + Input.location.lastData.horizontalAccuracy + " " + Input.location.lastData.timestamp); + yield return new WaitForSeconds(5f); + } + + // Stops the location service if there is no need to query location updates continuously. + yield return _coroutineHost.StartCoroutine(GPSService()); + } } } \ No newline at end of file diff --git a/Assets/GameManager/ITask.cs b/Assets/GameManager/ITask.cs index 11d1362..3c1bfef 100644 --- a/Assets/GameManager/ITask.cs +++ b/Assets/GameManager/ITask.cs @@ -2,10 +2,10 @@ using GeoSus.Client; using System; using UnityEngine; -public enum TaskType +/*public enum TaskType { Task //TODO: Typy úkolù -} +}*/ @@ -14,7 +14,7 @@ public interface ITask public string TaskID { get; } // Unikátní ID úkolu pro server public TaskType TaskType { get; } // Typ úkolu public string TaskName { get; } // Viditelný název úkolu - public (double, double) TaskLocation { get; } // Polohy na mapì + public Position TaskLocation { get; } // Polohy na mapì public bool IsCompleted { get; } // Stav dokonèení úkolu void Initialize(Action onCompleted); // Vytvoøení tasku + naètení postupu @@ -27,7 +27,7 @@ public class Wires : ITask{ public string TaskID { get; set; } // Unikátní ID úkolu pro server public TaskType TaskType { get; set; } // Typ úkolu public string TaskName { get; set; } // Viditelný název úkolu - public (double, double) TaskLocation { get; set; } // Poloha na mapì + public Position TaskLocation { get; set; } // Poloha na mapì public bool IsCompleted { get; private set; } // Stav dokonèení úkolu private Action _onCompleted; diff --git a/Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss.meta b/Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss.meta deleted file mode 100644 index 7ee4f0b..0000000 --- a/Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d133669256f71014fade8f776dc9e12f -ScriptedImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 2 - userData: - assetBundleName: - assetBundleVariant: - script: {fileID: 12388, guid: 0000000000000000e000000000000000, type: 0} - disableValidation: 0 diff --git a/Packages/manifest.json b/Packages/manifest.json index 8e8fd7d..702f6be 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -7,7 +7,7 @@ "com.unity.ide.visualstudio": "2.0.25", "com.unity.localization": "1.5.9", "com.unity.multiplayer.center": "1.0.0", - "com.unity.remote-config": "4.2.3", + "com.unity.remote-config": "4.2.5", "com.unity.ugui": "2.0.0", "com.unity.modules.accessibility": "1.0.0", "com.unity.modules.ai": "1.0.0", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index e68e1de..3dba7d0 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -226,7 +226,7 @@ "url": "https://packages.unity.com" }, "com.unity.remote-config": { - "version": "4.2.3", + "version": "4.2.5", "depth": 0, "source": "registry", "dependencies": {