using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using BITKit.Mod; using UnityEngine; using YooAsset; namespace BITKit.Animations { [Serializable] public struct ScriptableMotionMatchingSingleton:IMotionMatchingService { public bool TryMatch(out IMotionMatchingObject value, string[] key)=>ScriptableMotionMatchingService.Singleton.TryMatch(out value,key); } public class ScriptableMotionMatchingService : MonoBehaviour,IMotionMatchingService { internal static ScriptableMotionMatchingService Singleton { get; private set; } internal static readonly ConcurrentDictionary Cache = new(); private ObjectMatcher _objects; private void Awake() { Singleton = this; } private void OnEnable() { ModService.OnReloaded += Rebuild; } private void Start() { Rebuild(); } private void OnDisable() { ModService.OnReloaded -= Rebuild; } public bool TryMatch(out IMotionMatchingObject value, string[] key) { value = Cache.GetOrAdd(MathE.GetHash(key),Add); return value is not null; IMotionMatchingObject Add(int hash) { if (_objects.TryMatch(out IMotionMatchingObject x, key) is false) { BIT4Log.Log($"找不到对应的MotionMatchingObject:{string.Join(",", key)}"); return null; } return x; } } private void Rebuild() { Cache.Clear(); var list = new List(); var tags = new []{nameof(IMotionMatchingObject)}; foreach (var x in YooAssets.GetAssetInfos(tags)) { var assetHandle =YooAssets.LoadAssetSync(x.AssetPath); assetHandle.WaitForAsyncComplete(); list.Add(assetHandle.AssetObject.As()); } _objects = new ObjectMatcher { list = list.ToArray(), }; } } }