iFactory.Cutting.Unity/Assets/Artists/Scripts/Variable/FTY_MaterialVariable.cs

128 lines
3.1 KiB
C#

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<string, GameObject> builtinModel;
[SerializeField] private Transform modelRoot;
private readonly List<Func<string>> delegates = new();
private readonly ConcurrentDictionary<string, string> 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<FTY_MaterialVariable>($"注册变量:{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<string>(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<GameObject>(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();
}
}
}
}