using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using AYellowpaper.SerializedCollections; using BITFactory.Cutting; using BITKit; using BITKit.Entities; using BITKit.Entities.Variables; using BITKit.IO; using BITKit.Mod; using UnityEngine; using YooAsset; namespace BITFactory { public class FTY_MaterialVariable : EntityBehavior { [Inject] private IVariable _variable; [SerializeReference,SubclassSelector] private IReference[] _tags; [SerializeReference, SubclassSelector] private ICuttingTool _cuttingTool; [SerializeReference, SubclassSelector] private IApplicationFile _applicationFile; [SerializeField] private SerializedDictionary builtinModel; [SerializeField] private Transform modelRoot; private readonly List> delegates = new(); private readonly ConcurrentDictionary mapping = new(); public override void OnStart() { base.OnStart(); _variable.OnVariableChanged += OnVariableChanged; OnVariableChanged(null,_variable.Variable); _applicationFile.DataHandle += OnDataHandle; _applicationFile.AddListener(nameof(FTY_MaterialVariable),OnData); ModService.OnModLoaded += OnModLoaded; ModService.OnModUnLoaded += OnModLoaded; OnModLoaded(null); } private void OnModLoaded(IMod _) { foreach (var x in delegates) { _variable.CollectVariables -= x; } mapping.Clear(); var infos = YooAssetUtils.RegisteredPackages .Select(x => YooAssets.GetPackage(x)!) .SelectMany(x => x.GetAssetInfos(_tags.Cast()).ToArray()) ; foreach (var assetInfo in infos) { _variable.CollectVariables += GetName; delegates.Add(GetName); mapping[GetName()] = assetInfo.PackageName; BIT4Log.Log($"注册变量:{GetName()}"); continue; string GetName() { return assetInfo.AssetPath; } } } public override void OnDestroyComponent() { _applicationFile.DataHandle -= OnDataHandle; _applicationFile.RemoveListener(nameof(FTY_MaterialVariable),OnData); ModService.OnModLoaded -= OnModLoaded; ModService.OnModUnLoaded -= OnModLoaded; } private void OnData(byte[] data) { _variable.Variable = BITBinary.Read(data); } private (string, byte[]) OnDataHandle() { return new(nameof(FTY_MaterialVariable), BITBinary.WriteAsBytes(_variable.Variable)); } private void OnVariableChanged(string arg1, string arg2) { if (builtinModel.TryGetValue(arg2, out var nextModel)) { modelRoot.gameObject.DestoryChilds(); Instantiate(nextModel,modelRoot); _cuttingTool.Rebuild(); return; } var task = YooAssets.GetPackage(mapping[arg2]).LoadAssetAsync(arg2); task.Completed += OnComplete; return; void OnComplete(AssetHandle assetHandle) { modelRoot.gameObject.DestoryChilds(); var go = assetHandle.InstantiateSync(modelRoot); go.transform.localPosition = Vector3.zero; go.transform.localRotation = Quaternion.identity; _cuttingTool.Rebuild(); } } } }