using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using BITKit.UX; using BITKit.SubSystems; using UnityEngine.UIElements; using Cysharp.Threading.Tasks; using System.Threading.Tasks; using System.Threading; namespace BITKit.Mark { public class MarkSystemUIToolkit : MonoBehaviour { public UXElement element; [SerializeField,SerializeReference, SubclassSelector] private References className; [SerializeField, SerializeReference, SubclassSelector] private IMarkSystem markSystem; Dictionary dictionary = new(); IPanel panel; CancellationToken cancellationToken; void Awake() { cancellationToken = gameObject.GetCancellationTokenOnDestroy(); } void Start() { panel = element.GetVisualElement().panel; if (markSystem is not null) { markSystem.OnAdd += OnAdd; markSystem.OnUpdate += OnUpdate; markSystem.OnRemove += OnRemove; } } void OnDestroy() { if (markSystem is not null) { markSystem.OnAdd -= OnAdd; markSystem.OnUpdate -= OnUpdate; markSystem.OnRemove -= OnRemove; } } void OnAdd(IMarkObject markObject) { GetOrCreate(markObject.GetID()); } async void OnRemove(IMarkObject markObject) { try { await UniTask.SwitchToMainThread(cancellationToken); if (dictionary.TryGetValue(markObject.GetID(), out var label)) { element.GetVisualElement().Remove(label); dictionary.Remove(markObject.GetID()); } } catch (System.Exception e) { if (e is not OperationCanceledException) throw; } } async void OnUpdate(IMarkObject markObject) { var cameraTrans = Camera.main.transform; try { await UniTask.SwitchToMainThread(); var active = markObject.GetAcitve(); var label = GetOrCreate(markObject.GetID()); if (active) { var pos = RuntimePanelUtils .CameraTransformWorldToPanel(panel, markObject.GetPostion(), Camera.main); pos.x = (pos.x - label.layout.width / 2); Rect elementRect = new() { position = pos, size = label.layout.size, }; label.text = markObject.GetDisplay(); label.transform.position = pos; if (Vector3.Dot(cameraTrans.forward, markObject.GetPostion() - cameraTrans.position) > 0) { label.SetActive(true); } else { label.SetActive(false); } } else { label.SetActive(false); } } catch (OperationCanceledException) { } catch (System.Exception) { throw; } } Label GetOrCreate(string id) { if (dictionary.TryGetValue(id, out var label)) { } else { label = new(); label.AddToClassList(className); label.style.position = Position.Absolute; dictionary.Add(id, label); element.GetVisualElement().Add(label); } return label; } } }