Files
Net.Like.Xue.Tokyo/Packages-Local/Com.Project.B.Unity/UX/UXCosmetics.cs
2025-06-24 23:49:13 +08:00

152 lines
5.4 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITKit;
using BITKit.Entities;
using BITKit.Mod;
using BITKit.UX;
using BITKit.WorldNode;
using Cysharp.Threading.Tasks;
using Microsoft.CodeAnalysis.Operations;
using Microsoft.Extensions.Logging;
using Net.Project.B.Cosmetics;
using UnityEngine;
using UnityEngine.UIElements;
using ILogger = Microsoft.Extensions.Logging.ILogger;
namespace Net.Project.B.UX
{
[Serializable]
public sealed class UXCosmeticsWorldProxy:IWorldNode
{
}
public class UXCosmetics<TRoot>: UIToolkitSubPanel<TRoot>, IUXCosmetics where TRoot: IUXPanel
{
private readonly IWrapper<CosmeticsCustomizeComponent> _cosmeticsCustomize;
private readonly ILogger<UXCosmetics<TRoot>> _logger;
private readonly IEntitiesService _entitiesService;
[UXBindPath("cosmetics-container")]
private VisualElement _cosmeticsContainer;
[UXBindPath("cosmetics-dragger",true)]
private VisualElement _cosmeticsDragger;
private VisualTreeAsset _template;
private readonly Dictionary<int, ScriptableCosmetics> _cosmeticsMap=new ();
private readonly Dictionary<int,VisualElement> _cosmeticsElementMap=new ();
public UXCosmetics(IServiceProvider serviceProvider, IEntitiesService entitiesService, ILogger<UXCosmetics<TRoot>> logger, IWrapper<CosmeticsCustomizeComponent> cosmeticsCustomize) : base(serviceProvider)
{
_entitiesService = entitiesService;
_logger = logger;
_cosmeticsCustomize = cosmeticsCustomize;
_cosmeticsCustomize.OnValueChanged += OnCosmeticsChanged;
}
private void OnCosmeticsChanged(CosmeticsCustomizeComponent arg1, CosmeticsCustomizeComponent arg2)
{
foreach (var (id,visualElement) in _cosmeticsElementMap)
{
if (arg1.ComponentIds.Contains(id))
{
visualElement.AddToClassList("selected");
}
else
{
visualElement.RemoveFromClassList("selected");
}
}
}
protected override async UniTask OnInitiatedAsync()
{
await base.OnInitiatedAsync();
_logger.LogInformation("正在获取所有饰品...");
_cosmeticsContainer.Clear();
_cosmeticsContainer.Create<Label>().text="加载中...";
await base.OnInitiatedAsync();
_template =await ModService.LoadAsset<VisualTreeAsset>("ui_cosmetics-template");
var objs = _entitiesService.QueryComponents<ScriptableCosmetics>().ToArray().ToDictionary(x=>x.ScriptableId,x=>x);
_logger.LogInformation($"找到{objs.Count}个资源,正在加载中...");
_cosmeticsContainer.Clear();
foreach (var (id,cosmetics) in objs)
{
var container = _cosmeticsContainer.Create(_template);
container.Get<Label>().text = cosmetics.Name;
container.Get<VisualElement>().style.backgroundImage = new(cosmetics.Icon);
_cosmeticsMap.Add(cosmetics.ScriptableId,cosmetics);
_cosmeticsElementMap.Add(cosmetics.ScriptableId,container);
container.Get<Button>().clicked += () =>
{
var value = _cosmeticsCustomize.Value;
if (value.ComponentIds.Add(cosmetics.ScriptableId))
{
foreach (var nextId in value.ComponentIds.ToArray())
{
if(nextId == id)continue;
if (!objs.TryGetValue(nextId, out var nextCosmetics)) continue;
if (Equals(nextCosmetics.CosmeticsClass, cosmetics.CosmeticsClass))
{
value.ComponentIds.Remove(nextId);
}
}
}
else
{
if (cosmetics.CosmeticsClass is not IRequiredCosmeticsClass)
value.ComponentIds.Remove(cosmetics.ScriptableId);
}
_cosmeticsCustomize.Value = value;
};
}
_cosmeticsContainer.RegisterCallback<GeometryChangedEvent>(x =>
{
IsVisible.SetElements(_cosmeticsContainer,x.newRect.size.sqrMagnitude>0);
});
if (_cosmeticsDragger is not null)
{
var isDragging = false;
_cosmeticsDragger.RegisterCallback<PointerDownEvent>(x => { isDragging = true; });
_cosmeticsDragger.RegisterCallback<PointerUpEvent>(x => { isDragging = false; });
_cosmeticsDragger.RegisterCallback<PointerMoveEvent>(x =>
{
if (!isDragging) return;
foreach (var (transform, _) in _entitiesService.QueryComponents<Transform, UXCosmeticsWorldProxy>())
{
transform.Rotate(-Vector3.up * x.deltaPosition.x);
}
});
}
}
}
}