129 lines
3.9 KiB
C#
129 lines
3.9 KiB
C#
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;
|
|
[SerializeReference, SubclassSelector] public References className;
|
|
Dictionary<string, Label> dictionary = new();
|
|
MarkSystem markSystem;
|
|
IPanel panel;
|
|
CancellationToken cancellationToken;
|
|
void Awake()
|
|
{
|
|
cancellationToken = gameObject.GetCancellationTokenOnDestroy();
|
|
}
|
|
void Start()
|
|
{
|
|
panel = element.GetVisualElement().panel;
|
|
markSystem = BITSystems.GetOrCreate<MarkSystem>();
|
|
if (markSystem is not null)
|
|
{
|
|
markSystem.OnAdd += OnAdd;
|
|
markSystem.Update += OnUpdate;
|
|
markSystem.OnRemove += OnRemove;
|
|
}
|
|
}
|
|
void OnDestroy()
|
|
{
|
|
if (markSystem is not null)
|
|
{
|
|
markSystem.OnAdd -= OnAdd;
|
|
markSystem.Update -= 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;
|
|
}
|
|
}
|
|
} |