Net.Like.Xue.Tokyo/Assets/Artists/Scripts/UX/UXHud.cs

223 lines
7.7 KiB
C#
Raw Normal View History

2024-11-03 16:42:23 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using BITKit;
2025-02-26 15:34:59 +08:00
using BITKit.Entities;
2024-11-20 11:36:36 +08:00
using BITKit.Mod;
2024-11-03 16:42:23 +08:00
using BITKit.UX;
2025-02-26 15:34:59 +08:00
using BITKit.UX.Hotkey;
2024-11-03 16:42:23 +08:00
using BITKit.WorldNode;
using Cysharp.Threading.Tasks;
2025-03-03 18:44:00 +08:00
using Microsoft.Extensions.DependencyInjection;
2025-02-26 15:34:59 +08:00
using Net.Project.B.Emoji;
2024-11-03 16:42:23 +08:00
using Net.Project.B.Interaction;
2024-11-20 11:36:36 +08:00
using Net.Project.B.Quest;
2025-02-26 15:34:59 +08:00
using Net.Project.B.UX;
using Project.B.Entities;
2024-11-03 16:42:23 +08:00
using Project.B.Map;
2025-03-05 22:28:38 +08:00
using Project.B.Player;
2024-11-03 16:42:23 +08:00
using UnityEditor;
using UnityEngine;
2025-02-26 15:34:59 +08:00
using UnityEngine.InputSystem;
2024-11-03 16:42:23 +08:00
using UnityEngine.UIElements;
namespace Net.Like.Xue.Tokyo.UX
{
2025-03-05 22:28:38 +08:00
public class UXHud : UIToolKitPanel,IUXHud
2024-11-03 16:42:23 +08:00
{
2025-03-03 18:44:00 +08:00
private readonly IEntitiesService _entitiesService;
2025-02-26 15:34:59 +08:00
private readonly IPlayerFactory _playerFactory;
2024-11-03 16:42:23 +08:00
private readonly IGameMapService _gameMapService;
private readonly IWorldInteractionService _interactionService;
2024-11-20 11:36:36 +08:00
private readonly IQuestService _questService;
2025-02-26 15:34:59 +08:00
private readonly UXRadialMenu _radialMenu;
2025-03-05 22:28:38 +08:00
private readonly IUXKeyMap<InputAction> _uxKeyMap;
2025-02-26 15:34:59 +08:00
[Inject]
private IEmojiService<AnimationClip> _emojiService;
2025-03-05 22:28:38 +08:00
public UXHud(IUXService uxService, IGameMapService gameMapService, IWorldInteractionService interactionService, IQuestService questService, UXRadialMenu radialMenu, IPlayerFactory playerFactory, IEntitiesService entitiesService, IUXKeyMap<InputAction> uxKeyMap) : base(uxService)
2024-11-03 16:42:23 +08:00
{
_gameMapService = gameMapService;
_interactionService = interactionService;
2024-11-20 11:36:36 +08:00
_questService = questService;
2025-02-26 15:34:59 +08:00
_radialMenu = radialMenu;
_playerFactory = playerFactory;
2025-03-03 18:44:00 +08:00
_entitiesService = entitiesService;
2025-03-05 22:28:38 +08:00
_uxKeyMap = uxKeyMap;
2024-11-03 16:42:23 +08:00
2025-03-12 22:46:37 +08:00
_gameMapService.OnMapChangeCompleted += OnMapChanged;
2024-11-03 16:42:23 +08:00
_interactionService.OnInteraction += OnInteraction;
2024-11-20 11:36:36 +08:00
Data.AddListener<float>("Time",x=>
{
_timeSlider?.SetValueWithoutNotify(x);
});
_questService.OnQuestCreatedOrUpdated +=(x,y,z)=>_questQueue.Enqueue(new(x,y,z));
foreach (var (index,quest) in _questService.Quests)
{
_questQueue.Enqueue(new(quest,QuestState.Inactive,quest.CurrentState));
}
2025-02-26 15:34:59 +08:00
_playerFactory.OnEntityCreated += OnEntityCreated;
2025-03-05 22:28:38 +08:00
OnInitiatedAsync += InitiatedAsync;
}
private async UniTask InitiatedAsync()
{
_timeSlider.RegisterValueChangedCallback(x => { Data.Set("Time", x.newValue); });
_questContainer.Clear();
_questTemplate =await ModService.LoadAsset<VisualTreeAsset>("ux_quest_template");
_timeSlider.value = Data.Get<float>("Time");
2025-02-26 15:34:59 +08:00
}
private UniTask OnEntityCreated(string arg1, IEntity arg2)
{
arg2.Inject(this);
return UniTask.CompletedTask;
2024-11-03 16:42:23 +08:00
}
private void OnInteraction(object arg1, IWorldInteractable arg2, WorldInteractionProcess arg3, object arg4)
{
switch (arg3)
{
case WorldInteractionProcess.Hover:
_interactionTips.SetActive(true);
2025-03-05 22:28:38 +08:00
if (_entitiesService.Entities.TryGetValue( arg2.WorldObject.As<GameObject>().GetInstanceID(), out var entity) &&
2025-03-03 18:44:00 +08:00
entity.ServiceProvider.GetService<WorldInfoNode>() is { } infoNode && string.IsNullOrEmpty(infoNode.Name) is false)
{
_interactionTips.text = infoNode.Name;
}
else
{
_interactionTips.text = "互动";
}
2024-11-03 16:42:23 +08:00
break;
default:
_interactionTips.SetActive(false);
break;
}
}
private void OnMapChanged(Guid arg1, string arg2)
{
2025-03-05 22:28:38 +08:00
UXService.Entry<IUXHud>();
2024-11-03 16:42:23 +08:00
}
protected override string DocumentPath => "ux_hud";
public override bool AllowInput => true;
public override bool AllowCursor => false;
2025-03-03 18:44:00 +08:00
2024-11-03 16:42:23 +08:00
[UXBindPath("interaction-tips")]
private Label _interactionTips;
2024-11-20 11:36:36 +08:00
[UXBindPath("time-slider")]
private Slider _timeSlider;
[UXBindPath("quest-container")]
private VisualElement _questContainer;
2024-11-03 16:42:23 +08:00
private Camera _minimapCamera;
private Camera _mainCamera;
2024-11-20 11:36:36 +08:00
private VisualTreeAsset _questTemplate;
private readonly Queue<(IQuestData questData, QuestState oldQuestState, QuestState newQuestState)> _questQueue =
new();
2025-02-28 21:17:03 +08:00
private readonly Dictionary<int, VisualElement> _questContainers = new();
2024-11-20 11:36:36 +08:00
2024-11-03 16:42:23 +08:00
public override async UniTask EntryAsync()
{
await base.EntryAsync();
_interactionTips.SetActive(false);
2025-03-05 22:28:38 +08:00
2024-11-03 16:42:23 +08:00
}
2025-02-26 15:34:59 +08:00
public override async void OnTick(float deltaTime)
2024-11-03 16:42:23 +08:00
{
base.OnTick(deltaTime);
if(RootVisualElement is null)return;
2025-02-26 15:34:59 +08:00
if (Keyboard.current is { capsLockKey: { wasPressedThisFrame: true } } or {mKey:{wasPressedThisFrame:true}})
2024-11-03 16:42:23 +08:00
{
2025-03-03 18:44:00 +08:00
UXService.Entry<IUXMap>();
2025-02-26 15:34:59 +08:00
}else if (Keyboard.current is { f1Key: { wasPressedThisFrame: true } })
2024-11-03 16:42:23 +08:00
{
2025-02-26 15:34:59 +08:00
var collection = new HotkeyCollection();
_radialMenu.HotkeyCollection = collection;
foreach (var emojiData in await _emojiService.GetAllEmojis())
{
collection.Register(new HotkeyProvider()
{
Name = emojiData.Name,
Description = emojiData.Description,
Enabled = true,
OnPerform = () => _emojiService.Play(emojiData),
});
}
UXService.Entry(_radialMenu);
2024-11-03 16:42:23 +08:00
}
2024-11-20 11:36:36 +08:00
if (_questContainer is not null && _questTemplate!=null)
{
while (_questQueue.TryDequeue(out var quest))
{
2025-02-28 21:17:03 +08:00
if (quest.questData.IsCompleted)
{
if (_questContainers.TryGetValue(quest.questData.Identity, out var visualElement))
{
visualElement.RemoveFromHierarchy();
}
}
else
{
var visualElement = _questContainer.Create(_questTemplate);
visualElement.Get<Label>(0).text = quest.questData.Name;
visualElement.Get<Label>(1).text = quest.questData.Description;
_questContainers.TryAdd(quest.questData.Identity, visualElement);
}{}
2024-11-20 11:36:36 +08:00
}
}
2025-02-26 15:34:59 +08:00
2024-11-03 16:42:23 +08:00
}
2025-03-05 22:28:38 +08:00
protected override void OnPanelEntry()
{
base.OnPanelEntry();
InputActionGroup.RegisterCallback(_uxKeyMap.CancelKey, OnCancel);
InputActionGroup.RegisterCallback(_uxKeyMap.InventoryKey,OnInventory);
}
private void OnInventory(InputAction.CallbackContext obj)
{
if(obj.JustPressed() is false)return;
UXService.Entry<IUXInventory>();
}
private void OnCancel(InputAction.CallbackContext obj)
{
if (obj.JustPressed() is false) return;
UXService.Entry<UXEscMenu>();
}
protected override void OnPanelExit()
{
base.OnPanelExit();
InputActionGroup.UnRegisterCallback(_uxKeyMap.CancelKey, OnCancel);
InputActionGroup.UnRegisterCallback(_uxKeyMap.InventoryKey, OnInventory);
}
2024-11-03 16:42:23 +08:00
}
}