iFactory.Cutting.Unity/Assets/BITKit/Unity/Scripts/MotionMatching/ScriptableMotionMatchingSer...

78 lines
1.9 KiB
C#

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<int, IMotionMatchingObject> Cache = new();
private ObjectMatcher<string,IMotionMatchingObject> _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<ScriptableMotionMatchingService>($"找不到对应的MotionMatchingObject:{string.Join(",", key)}");
return null;
}
return x;
}
}
private void Rebuild()
{
Cache.Clear();
var list = new List<ScriptableMotionMatchingObject>();
var tags = new []{nameof(IMotionMatchingObject)};
foreach (var x in YooAssets.GetAssetInfos(tags))
{
var assetHandle =YooAssets.LoadAssetSync<ScriptableMotionMatchingObject>(x.AssetPath);
assetHandle.WaitForAsyncComplete();
list.Add(assetHandle.AssetObject.As<ScriptableMotionMatchingObject>());
}
_objects = new ObjectMatcher<string, IMotionMatchingObject>
{
list = list.ToArray(),
};
}
}
}