BITKit/Packages/Runtime~/Unity/Common/Scripts/MarkSystem/MarkSystemUIToolkit.cs

129 lines
3.9 KiB
C#
Raw Normal View History

2023-06-05 19:57:17 +08:00
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;
}
}
}