using Assets.Scripts.Models; using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class PlayerController : MonoBehaviour { public static PlayerController instance; public Dictionary<uint, List<Structure>> Workers = new Dictionary<uint, List<Structure>>(); public List<Structure> TestStructures = new List<Structure>(); public GameObject WorkersList; // scroll content public GameObject DateTimePanel; public GameObject StartHour; public GameObject StartMin; public GameObject StartSec; public GameObject EndHour; public GameObject EndMin; public GameObject EndSec; public GameObject StartStopButton; public LocationZones locationZones; public Dropdown DropdownMode; public Toggle ToggleLine; public Toggle ToggleDisappearance; Toggle ToggleCoordinate; public GameObject DatePicker; Camera camera; public GameObject UserInfo; public GameObject Editor; public uint? user_broadcast = null; public bool broadcast = false; public Dictionary<uint, User> users; public enum Mode { RealTime = 0, History = 1, Stop = 2 }; public Mode active_mode = Mode.Stop; //int mode = 0; Client client; CompanyController company; EditorController editor; DateTimePicker Date; public Dictionary<uint, bool> end_send = new Dictionary<uint, bool>(); // флаги завершения загрузки Dictionary<uint, MarkerMoving> moving = new Dictionary<uint, MarkerMoving>(); // флаги начала движения const float INTERPOLATION_PERIOD = 0.1f; float time_draw = 0; public bool users_load = false; // ожидание массива пользователей public bool beacons_load = false; //List<bool> StartStop = new List<bool>(); private void Awake() { instance = this; } // Start is called before the first frame update void Start() { DebugHelper.ActivateConsole(); client = Client.instance; company = CompanyController.instance; editor = Editor.GetComponent<EditorController>(); camera = Camera.main; //users = new Dictionary<uint, User>(); Date = DatePicker.GetComponent<DateTimePicker>(); //Client.LocationsRequest(); var broadcast_stop = UserInfo.transform.GetChild(1).GetChild(1).GetComponent<Button>(); broadcast_stop.onClick.AddListener(() => BroadcastStop()); ToggleCoordinate = GameObject.Find("ToggleCoordinate").GetComponent<Toggle>(); } // Update is called once per frame void Update() { //if (DropdownMode.value != mode) // СhangeMode(); DropdownMode.onValueChanged.AddListener(delegate { СhangeMode(); }); if (active_mode != Mode.Stop) { time_draw += Time.deltaTime; if (time_draw >= INTERPOLATION_PERIOD) { MarkerMove(); time_draw -= INTERPOLATION_PERIOD; } } if (users != null) { if (users_load == false) { foreach (var u in users.Values) { if (u.marker_line != null) { u.marker_line.gameObject.SetActive(ToggleLine.isOn); if (ToggleLine.isOn == false) u.marker_line.positionCount = 0; } } } if (users_load) { users_load = false; foreach (var u in users.OrderBy(u => u.Value.id)) { u.Value.SetParam(BroadcastStart); //if (DropdownMode.value == 0) u.Value.toggle_user.SetActive(u.Value.online); //else u.Value.toggle_user.SetActive(true); } } } ToggleDisappearance.interactable = ToggleLine.isOn; } /// <summary> /// Смена положения маркера /// </summary> /// <param name="step">Шаг до нового положения</param> /// <param name="start_pos">Начальное положение</param> /// <param name="end_pos">Финальное положение</param> /// <param name="user">Маркер сотрудника</param> /// <param name="w">Данные из БД</param> /// <param name="progress">Номер записи из БД</param> /// <returns></returns> void Position(float step, Vector3 start_pos, Vector3 end_pos, User user, Structure w, string progress) { Debug.LogWarning($"move user {user.id} {end_pos} {w.ts} {w.zone_id}"); if (user.marker.activeSelf == true) { var x_position = Mathf.Lerp(start_pos.x, end_pos.x, step); var y_position = Mathf.Lerp(start_pos.z, end_pos.z, step); //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}"); var new_position = new Vector3(x_position, 0.5f, y_position); if (user.marker.transform.position != new_position) { user.marker.transform.position = new Vector3(x_position, 0.5f, y_position); user.marker_line.SetPosition(user.marker_line.positionCount++, new Vector3(x_position, 0, y_position)); if (ToggleDisappearance.isOn) user.marker_line = LineDisappearance(user.marker_line); } var t = user.marker.transform.GetChild(0).transform.GetChild(0).transform.GetChild(0).GetComponent<Text>(); if (ToggleCoordinate.isOn) t.text = $"{w.acc_id} x={end_pos.x} y={end_pos.z}"; else t.text = $"{w.acc_id}\n{user.name_user}"; user.toggle.transform.GetChild(1).gameObject.GetComponent<Text>().text = $"{w.acc_id} {w.ts:HH:mm:ss}{progress}"; } } /// <summary> /// Запуск отрисовки /// </summary> public void ButtonStart() { if (active_mode == Mode.Stop) foreach (var u in users) u.Value.marker_line.positionCount = 0; var button_text = StartStopButton.transform.GetChild(0); switch (DropdownMode.value) { case 0: //real_time = !real_time; if (active_mode == Mode.Stop/*real_time*/) { active_mode = Mode.RealTime; button_text.GetComponent<Text>().text = "Остановить"; } else { active_mode = Mode.Stop; button_text.GetComponent<Text>().text = "Отобразить"; } break; case 1: if (active_mode == Mode.Stop/*real_time*/) active_mode = Mode.History; else active_mode = Mode.Stop; if (active_mode == Mode.History/*history_start*/) { var date = Date.Date; var time_start = date; //new DateTime(dates.ElementAt(DropdownData.value).Ticks); time_start = time_start.AddHours(int.Parse(StartHour.GetComponent<InputField>().text)); time_start = time_start.AddMinutes(int.Parse(StartMin.GetComponent<InputField>().text)); time_start = time_start.AddSeconds(int.Parse(StartSec.GetComponent<InputField>().text)); Debug.Log(time_start); var time_end = date; //new DateTime(dates.ElementAt(DropdownData.value).Ticks); time_end = time_end.AddHours(int.Parse(EndHour.GetComponent<InputField>().text)); time_end = time_end.AddMinutes(int.Parse(EndMin.GetComponent<InputField>().text)); time_end = time_end.AddSeconds(int.Parse(EndSec.GetComponent<InputField>().text)); foreach (var u in users) { if (u.Value.toggle.isOn) { client.CoordinatesRequest(time_start.Ticks, time_end.Ticks, 1, company.locations_index[company.active_location], u.Value.id); end_send[u.Value.id] = false; } } button_text.GetComponent<Text>().text = "Остановить"; } else { StopProgress(); } break; } } public void StopProgress() { StartStopButton.transform.GetChild(0).GetComponent<Text>().text = "Отобразить"; active_mode = Mode.Stop; if(users != null) foreach (var u in users) { end_send[u.Value.id] = false; moving.Remove(u.Value.id); } } /// <summary> /// Затухание траектории /// </summary> /// <param name="lineRenderer">Траектория</param> /// <returns></returns> LineRenderer LineDisappearance(LineRenderer lineRenderer) { //LineRenderer lineRenderer = GetComponent<LineRenderer>(); int newPositionCount = lineRenderer.positionCount - 1; Vector3[] newPositions = new Vector3[newPositionCount]; for (int i = 0; i < newPositionCount; i++) { newPositions[i] = lineRenderer.GetPosition(i + 1); } lineRenderer.SetPositions(newPositions); return lineRenderer; } /// <summary> /// Смена положения по интервалу /// Шаги для плавного перемещения /// </summary> /// <param name="u">Данные о маркере</param> void StartingAccPositiong(User u) { int i = 0; float step = 0.1f; if (moving.ContainsKey(u.id)) { if (moving[u.id].index < Workers[u.id].Count) i = moving[u.id].index; if (moving[u.id].step < 1.1f) step = moving[u.id].step; } else moving[u.id] = new MarkerMoving(); var worker = Workers[u.id]; Debug.LogWarning($"worker coord count {u.id} {worker.Count}"); if (active_mode == Mode.RealTime) worker = worker.OrderBy(wr => wr.ts).ToList(); if (worker.Any()) { var w = worker[i]; locationZones.UserPosition(u, w); var start_pos = u.marker.transform.position; if (i != 0) start_pos = new Vector3(worker[i - 1].coord_x, 0.5f, worker[i - 1].coord_y); if (active_mode == Mode.History && i == 0) start_pos = new Vector3(w.coord_x, 0.5f, w.coord_y); var end_pos = new Vector3(w.coord_x, 0.5f, w.coord_y); var progress = ""; if (active_mode == Mode.History) progress = $"\n{i + 1} из {Workers[u.id].Count}"; //if (starting) Position(step, start_pos, end_pos, u, w, progress); // StartingAccPositiong(m.value, time_step); } step += INTERPOLATION_PERIOD; // 0.1f; moving[u.id].step = step; if (Math.Round(step, 1) > 1) { Debug.Log($"step:{step}"); i++; moving[u.id].index = i; } if (active_mode == Mode.RealTime) if (Math.Round(step, 1) > 1) { Debug.Log($"Mode.RealTime step:{step}"); Workers.Remove(u.id); Debug.LogWarning($"clear coord user {u.id}"); } if (active_mode == Mode.History) if (i == Workers[u.id].Count) { //StopProgress(); Workers.Remove(u.id); } } /// <summary> /// Отображение маяков /// </summary> /// <param name="b"></param> //public static void AddBeacon(Beacon b) //{ // var beacon = Instantiate(Resources.Load("GameObjects/Beacon", typeof(GameObject))) as GameObject; // beacon.transform.position = new Vector3(b.x, 0.5f, b.y); // beacon.name = $"BeaconButton_{b.id}"; // beacon.GetComponent<BeaconController>().info = false; // beacon.transform.SetParent(GameObject.Find("Beacons").transform); // beacon.transform.GetChild(0).GetChild(0).GetChild(0).GetComponent<Text>().text = $"{b.id}\nuuid={b.uuid}\nmajor={b.major}\nminor={b.minor}"; // b.beacon = beacon; //} /// <summary> /// Остановка отрисовки при смене режима история/онлайн /// </summary> public void СhangeMode() { StopProgress(); active_mode = Mode.Stop; foreach (var u in users) u.Value.UserCompany(); //mode = DropdownMode.value; //switch (DropdownMode.value) //{ // case 0: // DateTimePanel.SetActive(false); // if (users != null) // foreach (var u in users) // { // if(!u.Value.online) u.Value.toggle.isOn = false; // u.Value.toggle_user.SetActive(u.Value.online); // } // break; // case 1: // DateTimePanel.SetActive(true); // if (users != null) // foreach (var u in users) // u.Value.toggle_user.SetActive(true); // break; //} } /// <summary> /// Смена позиции маркера /// </summary> public void MarkerMove() { if(users != null) foreach (var u in users) { if (u.Value != null) { //if (u.Value.marker.activeSelf != u.Value.toggle.isOn) u.Value.marker.SetActive(u.Value.toggle.isOn); if (active_mode == Mode.RealTime && u.Value.toggle.isOn && !Workers.ContainsKey(u.Value.id)) { Debug.LogWarning($"send coord user {u.Value.id}"); var index = company.locations_index[company.active_location]; client.CoordinatesRequest(0, 0, 1, company.locations[index].id, u.Value.id); u.Value.toggle_user.SetActive(u.Value.online); } if (u.Value.toggle.isOn && Workers.ContainsKey(u.Value.id) && active_mode != Mode.Stop/*&& starting*/ /*&& end_send[m.value.acc_id]*/) { StartingAccPositiong(u.Value); if (active_mode == Mode.History && !Workers.Any()) { //var temp = Workers.Values.Max(v => v.Count); //if (m.i == temp - 1 && moving[moving.Keys.Last()].step >= 1f) //{ StopProgress(); //} //if (active_mode == Mode.RealTime && moving[moving.Keys.Last()].index == 1) //{ // starting = false; //} } } } } } public void BroadcastStart(uint id) { if (user_broadcast.HasValue) { client.ImageStreamStopSend(user_broadcast.Value); var camera_button = users[user_broadcast.Value].toggle_user.transform.GetChild(1).GetComponent<Button>(); camera_button.GetComponent<Image>().color = Color.white; broadcast = false; } if (user_broadcast != id) { client.ImageStreamStartSend(id); user_broadcast = id; var name = UserInfo.transform.GetChild(1).GetChild(0).GetComponent<Text>(); name.text = $"{id} {users[id].name_user}"; name.GetComponent<RectTransform>().sizeDelta = new Vector2(name.preferredWidth, 30); var camera_button = users[id].toggle_user.transform.GetChild(1).GetComponent<Button>(); camera_button.GetComponent<Image>().color = Color.green; UserInfo.SetActive(false); broadcast = true; } else { broadcast = false; user_broadcast = null; UserInfo.SetActive(false); } } public void BroadcastStop() { if (user_broadcast.HasValue) { client.ImageStreamStopSend(user_broadcast.Value); var camera_button = users[user_broadcast.Value].toggle_user.transform.GetChild(1).GetComponent<Button>(); camera_button.GetComponent<Image>().color = Color.white; } broadcast = false; user_broadcast = null; UserInfo.SetActive(false); } }