PlayerController.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. using Assets.Scripts.Models;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Threading;
  7. using UnityEngine;
  8. using UnityEngine.SceneManagement;
  9. using UnityEngine.UI;
  10. public class PlayerController : MonoBehaviour
  11. {
  12. public static PlayerController instance;
  13. public Dictionary<uint, List<Structure>> Workers = new Dictionary<uint, List<Structure>>();
  14. public List<Structure> TestStructures = new List<Structure>();
  15. //public List<Beacon> Beacons = new List<Beacon>();
  16. public GameObject WorkersList; // scroll content
  17. public GameObject DateTimePanel;
  18. public GameObject StartHour;
  19. public GameObject StartMin;
  20. public GameObject StartSec;
  21. public GameObject EndHour;
  22. public GameObject EndMin;
  23. public GameObject EndSec;
  24. public GameObject StartStopButton;
  25. //public GameObject ErrorDialog;
  26. public Dropdown DropdownMode;
  27. public Toggle ToggleLine;
  28. public Toggle ToggleDisappearance;
  29. public GameObject DatePicker;
  30. Camera camera;
  31. public Toggle projection;
  32. //public GameObject LocationGameObject;
  33. public GameObject UserInfo;
  34. public GameObject Editor;
  35. public uint? user_broadcast = null;
  36. public bool broadcast = false;
  37. public List<Marker> markers;
  38. public enum Mode { RealTime = 0, History = 1, Stop = 2 };
  39. public static Mode active_mode = Mode.Stop;
  40. int mode = 0;
  41. //public GameObject Time;
  42. Client client;
  43. static EditorController editor;
  44. CompanyController company;
  45. DateTimePicker Date;
  46. //public List<GameObject> maps;
  47. static bool starting = false; // флаг остановки
  48. public Dictionary<uint, bool> end_send = new Dictionary<uint, bool>(); // флаги завершения загрузки
  49. Dictionary<uint, MarkerMoving> moving = new Dictionary<uint, MarkerMoving>(); // флаги начала движения
  50. const float INTERPOLATION_PERIOD = 0.1f;
  51. //float time_realtime = 0;
  52. float time_draw = 0;
  53. public List<User> users = new List<User>();
  54. public bool users_load = false;
  55. public bool beacons_load = false;
  56. //List<bool> StartStop = new List<bool>();
  57. private void Awake()
  58. {
  59. instance = this;
  60. }
  61. // Start is called before the first frame update
  62. void Start()
  63. {
  64. DebugHelper.ActivateConsole();
  65. client = Client.instance;
  66. company = CompanyController.instance;
  67. editor = Editor.GetComponent<EditorController>();
  68. camera = Camera.main;
  69. markers = new List<Marker>();
  70. Date = DatePicker.GetComponent<DateTimePicker>();
  71. //locations.Add(new Location { id = 1, name = "1 Братск" });
  72. //locations.Add(new Location { id = 22, name = "22 Офис Ижевск" });
  73. //locations.Add(new Location { id = 25, name = "25" });
  74. //locations.Add(new Location { id = 26, name = "26 Братское (вагрант)" });
  75. //foreach (var l in locations)
  76. // DropdownLocation.options.Add(new Dropdown.OptionData(l.name));
  77. //for (int i = 0; i < Locations.transform.childCount; i++)
  78. // maps.Add(Locations.transform.GetChild(i).gameObject);
  79. //Client.LocationsRequest();
  80. var broadcast_stop = UserInfo.transform.GetChild(1).GetChild(1).GetComponent<Button>();
  81. broadcast_stop.onClick.AddListener(() => BroadcastStop());
  82. }
  83. // Update is called once per frame
  84. void Update()
  85. {
  86. if (DropdownMode.value != mode)
  87. СhangeMode();
  88. time_draw += Time.deltaTime;
  89. if (time_draw >= INTERPOLATION_PERIOD)
  90. {
  91. MarkerMove();
  92. time_draw -= INTERPOLATION_PERIOD;
  93. }
  94. //if (active_mode == Mode.RealTime && !starting)
  95. //{
  96. // foreach (var m in markers)
  97. // {
  98. // if (m.toggle.isOn)
  99. // {
  100. // Debug.LogWarning($"send {m.acc_id}");
  101. // var index = company.locations_index[company.active_location];
  102. // client.CoordinatesRequest(0, 0, 1, company.locations[index].id, m.acc_id);
  103. // //end_send[m.acc_id] = false;
  104. // }
  105. // }
  106. // starting = true;
  107. //}\\\\\
  108. if (ToggleLine.isOn)
  109. {
  110. foreach (var m in markers)
  111. m.marker_line.gameObject.SetActive(true);
  112. ToggleDisappearance.interactable = true;
  113. }
  114. else
  115. {
  116. foreach (var m in markers)
  117. {
  118. m.marker_line.gameObject.SetActive(false);
  119. m.marker_line.positionCount = 0;
  120. }
  121. ToggleDisappearance.interactable = false;
  122. }
  123. if (projection.isOn)
  124. {
  125. camera.orthographic = true;
  126. }
  127. else
  128. {
  129. camera.orthographic = false;
  130. }
  131. if (users_load)
  132. {
  133. users_load = false;
  134. foreach (var u in users.OrderBy(u => u.id))
  135. WorkerMarker(u, Color.green);
  136. }
  137. //LoadMaps(DropdownLocation, Locations);
  138. //if (locations.Any() && AuthorizationController.success)
  139. //{
  140. // active_location = DropdownLocation.value;
  141. // LoadLocation(locations[active_location]);
  142. //}
  143. }
  144. /// <summary>
  145. /// Создание маркера для сотрудника
  146. /// </summary>
  147. /// <param name="acc_id"></param>
  148. void WorkerMarker(User user, Color color)
  149. {
  150. var toggle_user = Instantiate(Resources.Load("GameObjects/ToggleUser", typeof(GameObject))) as GameObject;
  151. toggle_user.name = $"{user.id}";
  152. var toggle = toggle_user.transform.GetChild(0).GetComponent<Toggle>();
  153. toggle.transform.GetChild(1).gameObject.GetComponent<Text>().text = $"{user.id} {user.name}";
  154. toggle_user.transform.SetParent(WorkersList.transform);
  155. toggle.isOn = false;
  156. var camera_button = toggle_user.transform.GetChild(1).GetComponent<Button>();
  157. camera_button.onClick.AddListener(() => BroadcastStart(user.id));
  158. var marker = Instantiate(Resources.Load("GameObjects/Capsule", typeof(GameObject))) as GameObject;
  159. marker.name = $"marker_{user.id}";
  160. marker.transform.GetChild(0).transform.GetChild(0).transform.GetChild(0).GetComponent<Text>().text = $"{user.id}";
  161. marker.transform.SetParent(GameObject.Find("Markers").transform);
  162. marker.GetComponent<Renderer>().material.color = color; // UnityEngine.Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f);
  163. marker.GetComponent<LabelObjectScript>().UserId = user.id;
  164. var marker_line = Instantiate(Resources.Load("GameObjects/Line", typeof(LineRenderer))) as LineRenderer;
  165. marker_line.name = $"marker_line_{user.id}";
  166. marker_line.startColor = color;
  167. marker_line.endColor = Color.white;
  168. marker_line.material.color = color;
  169. marker_line.transform.SetParent(GameObject.Find("Markers").transform);
  170. markers.Add(new Marker { acc_id = user.id, marker = marker, toggle = toggle, marker_line = marker_line, toggle_user = toggle_user });
  171. }
  172. /// <summary>
  173. /// Смена положения маркера
  174. /// </summary>
  175. /// <param name="step">Шаг до нового положения</param>
  176. /// <param name="start_pos">Начальное положение</param>
  177. /// <param name="end_pos">Финальное положение</param>
  178. /// <param name="marker">Маркер сотрудника</param>
  179. /// <param name="w">Данные из БД</param>
  180. /// <param name="progress">Номер записи из БД</param>
  181. /// <returns></returns>
  182. void Position(float step, Vector3 start_pos, Vector3 end_pos, Marker marker, Structure w, string progress)
  183. {
  184. Debug.LogWarning($"move user {marker.acc_id} {end_pos} {w.ts} {w.zone_id}");
  185. if (marker.marker.activeSelf == true)
  186. {
  187. var x_position = Mathf.Lerp(start_pos.x, end_pos.x, step);
  188. var y_position = Mathf.Lerp(start_pos.z, end_pos.z, step);
  189. //Debug.Log($"marker name={worker_marker.name} time={pause} step={step} sec x={x_position} y={y_position} x0={start_pos.x} y0={start_pos.z} x1={end_pos.x} y1={end_pos.z}");
  190. var new_position = new Vector3(x_position, 0.5f, y_position);
  191. if (marker.marker.transform.position != new_position)
  192. {
  193. marker.marker.transform.position = new Vector3(x_position, 0.5f, y_position);
  194. marker.marker_line.SetPosition(marker.marker_line.positionCount++, new Vector3(x_position, 0, y_position));
  195. if (ToggleDisappearance.isOn) marker.marker_line = LineDisappearance(marker.marker_line);
  196. }
  197. marker.marker.transform.GetChild(0).transform.GetChild(0).transform.GetChild(0).GetComponent<Text>().text = $"{w.acc_id} x={end_pos.x} y={end_pos.z}";
  198. marker.toggle.transform.GetChild(1).gameObject.GetComponent<Text>().text = $"{w.acc_id} {w.ts:hh:mm:ss}{progress}";
  199. }
  200. }
  201. /// <summary>
  202. /// Запуск отрисовки
  203. /// </summary>
  204. public void ButtonStart()
  205. {
  206. if (active_mode == Mode.Stop)
  207. foreach (var m in markers)
  208. m.marker_line.positionCount = 0;
  209. var button_text = StartStopButton.transform.GetChild(0);
  210. switch (DropdownMode.value)
  211. {
  212. case 0:
  213. //real_time = !real_time;
  214. if (active_mode == Mode.Stop/*real_time*/)
  215. {
  216. active_mode = Mode.RealTime;
  217. button_text.GetComponent<Text>().text = "Остановить";
  218. }
  219. else
  220. {
  221. active_mode = Mode.Stop;
  222. button_text.GetComponent<Text>().text = "Отобразить";
  223. }
  224. break;
  225. case 1:
  226. if (active_mode == Mode.Stop/*real_time*/) active_mode = Mode.History;
  227. else active_mode = Mode.Stop;
  228. if (active_mode == Mode.History/*history_start*/)
  229. {
  230. starting = true;
  231. var date = Date.Date;
  232. var time_start = date; //new DateTime(dates.ElementAt(DropdownData.value).Ticks);
  233. time_start = time_start.AddHours(int.Parse(StartHour.GetComponent<InputField>().text));
  234. time_start = time_start.AddMinutes(int.Parse(StartMin.GetComponent<InputField>().text));
  235. time_start = time_start.AddSeconds(int.Parse(StartSec.GetComponent<InputField>().text));
  236. Debug.Log(time_start);
  237. var time_end = date; //new DateTime(dates.ElementAt(DropdownData.value).Ticks);
  238. time_end = time_end.AddHours(int.Parse(EndHour.GetComponent<InputField>().text));
  239. time_end = time_end.AddMinutes(int.Parse(EndMin.GetComponent<InputField>().text));
  240. time_end = time_end.AddSeconds(int.Parse(EndSec.GetComponent<InputField>().text));
  241. foreach (var m in markers)
  242. {
  243. if (m.toggle.isOn)
  244. {
  245. client.CoordinatesRequest(time_start.Ticks, time_end.Ticks, 1, company.locations_index[company.active_location], m.acc_id);
  246. end_send[m.acc_id] = false;
  247. }
  248. }
  249. button_text.GetComponent<Text>().text = "Остановить";
  250. }
  251. else
  252. {
  253. StopProgress();
  254. }
  255. break;
  256. }
  257. }
  258. public void StopProgress()
  259. {
  260. starting = false;
  261. StartStopButton.transform.GetChild(0).GetComponent<Text>().text = "Отобразить";
  262. active_mode = Mode.Stop;
  263. foreach (var m in markers)
  264. {
  265. end_send[m.acc_id] = false;
  266. moving.Remove(m.acc_id);
  267. }
  268. }
  269. /// <summary>
  270. /// Затухание траектории
  271. /// </summary>
  272. /// <param name="lineRenderer">Траектория</param>
  273. /// <returns></returns>
  274. LineRenderer LineDisappearance(LineRenderer lineRenderer)
  275. {
  276. //LineRenderer lineRenderer = GetComponent<LineRenderer>();
  277. int newPositionCount = lineRenderer.positionCount - 1;
  278. Vector3[] newPositions = new Vector3[newPositionCount];
  279. for (int i = 0; i < newPositionCount; i++)
  280. {
  281. newPositions[i] = lineRenderer.GetPosition(i + 1);
  282. }
  283. lineRenderer.SetPositions(newPositions);
  284. return lineRenderer;
  285. }
  286. /// <summary>
  287. /// Смена положения по интервалу
  288. /// Шаги для плавного перемещения
  289. /// </summary>
  290. /// <param name="m">Данные о маркере</param>
  291. void StartingAccPositiong(Marker m)
  292. {
  293. int i = 0;
  294. float step = 0.1f;
  295. if (moving.ContainsKey(m.acc_id))
  296. {
  297. if (moving[m.acc_id].index < Workers[m.acc_id].Count) i = moving[m.acc_id].index;
  298. if (moving[m.acc_id].step < 1.1f) step = moving[m.acc_id].step;
  299. }
  300. else moving[m.acc_id] = new MarkerMoving();
  301. var worker = Workers[m.acc_id];
  302. Debug.LogWarning($"worker coord count {m.acc_id} {worker.Count}");
  303. if (active_mode == Mode.RealTime) worker = worker.OrderBy(wr => wr.ts).ToList();
  304. if (worker.Any())
  305. {
  306. var w = worker[i];
  307. var start_pos = m.marker.transform.position;
  308. if (i != 0) start_pos = new Vector3(worker[i - 1].coord_x, 0.5f, worker[i - 1].coord_y);
  309. if (active_mode == Mode.History && i == 0) start_pos = new Vector3(w.coord_x, 0.5f, w.coord_y);
  310. var end_pos = new Vector3(w.coord_x, 0.5f, w.coord_y);
  311. var progress = "";
  312. if (active_mode == Mode.History) progress = $"\n{i + 1} из {Workers[m.acc_id].Count}";
  313. //if (starting)
  314. Position(step, start_pos, end_pos, m, w, progress);
  315. // StartingAccPositiong(m.value, time_step);
  316. }
  317. step += INTERPOLATION_PERIOD; // 0.1f;
  318. moving[m.acc_id].step = step;
  319. if (Math.Round(step, 1) > 1)
  320. {
  321. Debug.Log($"step:{step}");
  322. i++;
  323. moving[m.acc_id].index = i;
  324. }
  325. if (active_mode == Mode.RealTime)
  326. if (Math.Round(step, 1) > 1)
  327. {
  328. Debug.Log($"Mode.RealTime step:{step}");
  329. Workers.Remove(m.acc_id);
  330. Debug.LogWarning($"clear coord user {m.acc_id}");
  331. }
  332. if (active_mode == Mode.History)
  333. if (i == Workers[m.acc_id].Count)
  334. {
  335. //StopProgress();
  336. Workers.Remove(m.acc_id);
  337. }
  338. }
  339. /// <summary>
  340. /// Отображение маяков
  341. /// </summary>
  342. /// <param name="b"></param>
  343. public static void AddBeacon(Beacon b)
  344. {
  345. var beacon = Instantiate(Resources.Load("GameObjects/Beacon", typeof(GameObject))) as GameObject;
  346. beacon.transform.position = new Vector3(b.x, 0.5f, b.y);
  347. beacon.name = $"BeaconButton_{b.id}";
  348. beacon.GetComponent<BeaconController>().info = false;
  349. beacon.transform.SetParent(GameObject.Find("Beacons").transform);
  350. beacon.transform.GetChild(0).GetChild(0).GetChild(0).GetComponent<Text>().text = $"{b.id}\nuuid={b.uuid}\nmajor={b.major}\nminor={b.minor}";
  351. b.beacon = beacon;
  352. }
  353. void OnGUI()
  354. {
  355. //if (Input.GetKeyDown(KeyCode.BackQuote))
  356. DebugHelper.DrawConsole();
  357. }
  358. /// <summary>
  359. /// Остановка отрисовки при смене режима история/онлайн
  360. /// </summary>
  361. public void СhangeMode()
  362. {
  363. StopProgress();
  364. active_mode = Mode.Stop;
  365. mode = DropdownMode.value;
  366. switch (DropdownMode.value)
  367. {
  368. case 0:
  369. DateTimePanel.SetActive(false);
  370. break;
  371. case 1:
  372. DateTimePanel.SetActive(true);
  373. break;
  374. }
  375. }
  376. /// <summary>
  377. /// Смена позиции маркера
  378. /// </summary>
  379. public void MarkerMove()
  380. {
  381. foreach (var m in markers.Select((value, i) => (value, i)))
  382. {
  383. if (m.value.marker.activeSelf != m.value.toggle.isOn) m.value.marker.SetActive(m.value.toggle.isOn);
  384. if (active_mode == Mode.RealTime && m.value.toggle.isOn && !Workers.ContainsKey(m.value.acc_id))
  385. {
  386. Debug.LogWarning($"send coord user {m.value.acc_id}");
  387. var index = company.locations_index[company.active_location];
  388. client.CoordinatesRequest(0, 0, 1, company.locations[index].id, m.value.acc_id);
  389. }
  390. if (m.value.toggle.isOn && Workers.ContainsKey(m.value.acc_id) && active_mode != Mode.Stop/*&& starting*/ /*&& end_send[m.value.acc_id]*/)
  391. {
  392. StartingAccPositiong(m.value);
  393. if (active_mode == Mode.History && !Workers.Any())
  394. {
  395. //var temp = Workers.Values.Max(v => v.Count);
  396. //if (m.i == temp - 1 && moving[moving.Keys.Last()].step >= 1f)
  397. //{
  398. StopProgress();
  399. //}
  400. //if (active_mode == Mode.RealTime && moving[moving.Keys.Last()].index == 1)
  401. //{
  402. // starting = false;
  403. //}
  404. }
  405. }
  406. }
  407. }
  408. /// <summary>
  409. /// Загрузка объектов локации
  410. /// </summary>
  411. /// <param name="location"></param>
  412. //public void LoadLocation(Location location)
  413. //{
  414. // print("PlayerController.LoadLocation");
  415. // if (load_location_elements.ContainsKey(location.id))
  416. // {
  417. // location.Load();
  418. // }
  419. //}
  420. public void BroadcastStart(uint id)
  421. {
  422. if (user_broadcast.HasValue)
  423. client.ImageStreamStopSend(user_broadcast.Value);
  424. if (user_broadcast != id)
  425. {
  426. client.ImageStreamStartSend(id);
  427. user_broadcast = id;
  428. var name = UserInfo.transform.GetChild(1).GetChild(0).GetComponent<Text>();
  429. name.text = $"{id} {users.Single(u => u.id == id).name}";
  430. name.GetComponent<RectTransform>().sizeDelta =new Vector2( name.preferredWidth, 30);
  431. }
  432. else
  433. {
  434. user_broadcast = null;
  435. UserInfo.SetActive(false);
  436. }
  437. }
  438. public void BroadcastStop()
  439. {
  440. if (user_broadcast.HasValue)
  441. client.ImageStreamStopSend(user_broadcast.Value);
  442. user_broadcast = null;
  443. UserInfo.SetActive(false);
  444. }
  445. }