using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; using BITKit; using UnityEngine.Events; using UnityEngine.Pool; using UnityEngine.UIElements; namespace BITKit { public struct VFXMessage { public string path; public Location location; } public class VFXService : MonoBehaviour, IObjectMatcher { private static VFXService sinleton; public VFX[] vfxs; private readonly Dictionary> pools = new(); private readonly ConcurrentDictionary cache = new(); [SerializeField] private bool debug; [SerializeField] private Optional defaultCapacity; private void Awake() { cache.Clear(); sinleton = this; DI.Register(this); } public Transform Spawn(RaycastHit hit, params string[] keyWords) { return Spawn(new Location() { position = hit.point, rotation = Quaternion.LookRotation(hit.normal), forward = hit.normal, }, keyWords); } public Transform Spawn(Location location, params string[] keyWords) { StringBuilder reportBuilder = debug ? new() : null; reportBuilder?.AppendLine(JsonHelper.Get(keyWords)); if (TryMatch(out var prefab, keyWords)) { var pool = pools.Get(prefab.name); if (defaultCapacity.Allow) pool.DefaultCapacity = defaultCapacity.Value; var instance = pool.Get(prefab, transform); instance.SetPositionAndRotation(location, location); if (location.forward.sqrMagnitude is not 0) instance.forward = location.forward; reportBuilder?.AppendLine($"生成:{prefab.name}"); if(reportBuilder is not null) BIT4Log.Log(reportBuilder.ToString()); return instance; } else { BIT4Log.Log($"未找到:{JsonHelper.Get(keyWords)}"); return null; } } public bool TryMatch(out Transform value, params string[] key) { value=cache.GetOrAdd(MathE.GetHash(key),Add); return value is not null; Transform Add(int arg) { foreach (var vfx in vfxs) { if (vfx.IsMatch(key)) { var x = vfx.prefab; return x; } } return null; } } } }