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

233 lines
8.1 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using BITKit;
using BITKit.Entities;
using BITKit.Mod;
using BITKit.UX;
using Cysharp.Threading.Tasks;
using Net.BITKit.Localization;
using Project.B.Item;
using Project.B.Player;
using Project.B.UX;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace Net.Project.B.UX
{
public class UXItemInspector : UIToolKitPanel, IUXItemInspector
{
private readonly IEntitiesService _entitiesService;
private readonly IWrapper<PlayerSettings> _playerSettings;
private readonly ILocalizationService _localizationService;
protected override string DocumentPath => "ui_item_inspector";
public override bool AllowCursor => true;
private readonly IUXKeyMap<InputAction> _uxKeyMap;
private Camera _rendererCamera;
private UniTaskCompletionSource _closeSource;
private readonly Dictionary<string, ScriptableItem> _scriptableItems;
public UXItemInspector(IUXService uxService, IUXKeyMap<InputAction> uxKeyMap, ILocalizationService localizationService, IWrapper<PlayerSettings> playerSettings, IEntitiesService entitiesService) : base(uxService)
{
_uxKeyMap = uxKeyMap;
_localizationService = localizationService;
_playerSettings = playerSettings;
_entitiesService = entitiesService;
OnInitiated += Initiated;
_scriptableItems = _entitiesService.QueryComponents<ScriptableItem>().ToArray().ToDictionary(x => x.name);
}
private void Initiated()
{
var dropdown = RootVisualElement.Get<DropdownField>();
if (dropdown is not null)
{
dropdown.choices.Clear();
{
foreach (var lang in Enum.GetValues(typeof(Lang)).OfType<Lang>())
{
var code = lang.GetType().GetMember(lang.ToString())[0].GetCustomAttribute<DescriptionAttribute>().Description;
dropdown.choices.Add(code);
}
}
dropdown.value = _playerSettings.Value.Language;
dropdown.RegisterValueChangedCallback(x =>
{
var label = RootVisualElement.Get<Label>();
if (label.userData is string code)
{
label.text = _localizationService.GetLocalizedString(code, dropdown.value);
}
});
}
}
public async void Inspect(IRuntimeItem runtimeItem)
{
if (DictionaryReferenceScriptableObject.Dictionary.TryGetValue(runtimeItem.ScriptableId, out var address) is
false) return;
var scriptableItem = _scriptableItems[address];
var dropdown = RootVisualElement.Get<DropdownField>();
RootVisualElement.Get<VisualElement>().SetActive(true);
RootVisualElement.Get<VisualElement>().style.backgroundImage =
new(scriptableItem.RectangleIcon ? scriptableItem.RectangleIcon : scriptableItem.Icon);
RootVisualElement.Get<Label>().userData = scriptableItem.Name;
RootVisualElement.Get<Label>().text =_localizationService.GetLocalizedString( scriptableItem.Name,dropdown.value);
RootVisualElement.Get<Label>(1).text = _localizationService.GetLocalizedString(scriptableItem.Description,dropdown.value);
UXService.Entry(this);
if (!scriptableItem.Model) return;
var rot = Vector3.zero;
_closeSource?.TrySetCanceled();
_closeSource = new();
var image = RootVisualElement.Get<VisualElement>();
var rendererTexture = new RenderTexture(Screen.width/2,Screen.height/2, 32);
image.style.backgroundImage = Background.FromRenderTexture(rendererTexture);
var cameraObject = new GameObject();
_rendererCamera = cameraObject.AddComponent<Camera>();
_rendererCamera.targetTexture = rendererTexture;
_rendererCamera.backgroundColor = Color.clear;
_rendererCamera.nearClipPlane = 0.01F;
_rendererCamera.cullingMask = 32;
_rendererCamera.clearFlags=CameraClearFlags.SolidColor;
cameraObject.transform.position = Vector3.zero;
cameraObject.transform.rotation=Quaternion.identity;
var inspectModel =new GameObject().transform;
cameraObject.transform.parent = inspectModel;
inspectModel.position = Vector3.zero;
inspectModel = Object.Instantiate(scriptableItem.Model,inspectModel);
var bounds = new Bounds();
var isDragging=false;
foreach (var x in inspectModel.GetComponentsInChildren<Renderer>())
{
x.gameObject.layer = 5;
bounds.Encapsulate(x.bounds);
}
var length = bounds.size.GetLength() * 2;
image.RegisterCallback<WheelEvent>(OnWheelEvent);
image.RegisterCallback<PointerDownEvent>(OnPointerDown);
image.RegisterCallback<PointerUpEvent>(OnPointerUp);
image.RegisterCallback<PointerMoveEvent>(OnPointerMove);
inspectModel.position = new Vector3(0, -bounds.center.y, 0);
inspectModel = inspectModel.parent;
cameraObject.transform.localPosition = Vector3.back * bounds.size.GetLength() * 2;
await _closeSource.Task;
RootVisualElement.Get<VisualElement>().SetActive(false);
image.UnregisterCallback<WheelEvent>(OnWheelEvent);
image.UnregisterCallback<PointerDownEvent>(OnPointerDown);
image.UnregisterCallback<PointerUpEvent>(OnPointerUp);
image.UnregisterCallback<PointerMoveEvent>(OnPointerMove);
Object.Destroy(cameraObject);
Object.Destroy(inspectModel.gameObject);
Object.Destroy(rendererTexture);
return;
void OnWheelEvent(WheelEvent evt)
{
length += evt.delta.y*Time.deltaTime;
Update();
}
void OnPointerDown(PointerDownEvent evt)
{
isDragging = true;
}
void OnPointerUp(PointerUpEvent evt)
{
isDragging = false;
}
void OnPointerMove(PointerMoveEvent evt)
{
if(isDragging is false)return;
rot += evt.deltaPosition;
Update();
}
void Update()
{
var newRot = Quaternion.Euler(rot.y, rot.x, 0);
cameraObject.transform.localRotation= newRot;
cameraObject.transform.localPosition = newRot * Vector3.back * length;
}
}
protected override void OnPanelEntry()
{
base.OnPanelEntry();
InputActionGroup.RegisterCallback(_uxKeyMap.CancelKey, OnReturn);
InputActionGroup.RegisterCallback(_uxKeyMap.InventoryKey, OnInventory);
}
private void OnInventory(InputAction.CallbackContext obj)
{
if(obj.performed is false)return;
UXService.Entry<IUXInventory>();
}
private void OnReturn(InputAction.CallbackContext obj)
{
if(obj.performed is false)return;
UXService.Entry<IUXHud>();
}
protected override void OnPanelExit()
{
base.OnPanelExit();
InputActionGroup.UnRegisterCallback(_uxKeyMap.CancelKey, OnReturn);
InputActionGroup.UnRegisterCallback(_uxKeyMap.InventoryKey, OnInventory);
_closeSource?.TrySetResult();
}
}
}