using RuntimeGizmos; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEngine; using UnityEngine.UI; public class KF3ModelBuilder : ModelBuilder { public static KF3ModelBuilder Instance => GetInstance(); private KF3ModelViewerMain Main => KF3ModelViewerMain.Instance; public IEnumerator Init(Action callback) { callback(this); yield break; } public IEnumerator BuildCharacter(string modelName, string animSetName, Action callback = null) { yield return KF3FriendContainer.CreateAsync(modelName, animSetName, false, (container)=> { Main.SelectObject(container); callback?.Invoke(container.gameObject); }); } public IEnumerator BuildCerulean(string modelName, string animSetName, Action callback = null) { yield return KF3CeruleanContainer.CreateAsync(modelName, animSetName, (container) => { Main.SelectObject(container); callback?.Invoke(container.gameObject); }); } public override IEnumerator SpawnSerializedCoroutine(ObjectContainerSerializable oc, Action callback = null) { return SpawnSerialized(oc as KF3ObjectContainerSerializable, callback); } public IEnumerator SpawnSerialized(KF3ObjectContainerSerializable oc, Action callback = null) { switch (oc) { case KF3CharacterContainerSerializable cs: if (cs.IsCerulean) { var celName = Main.Assets.Ceruleans.FirstOrDefault(c => c.FileName == cs.CostumeName); yield return BuildCerulean(celName.FileName, celName.FileName, (go) => { var cont = go.GetComponent(); cont.PasteContainer(cs, new PoseLoadOptions(true)); cont.DeserializeFrames(cs); TimelineController.SetCurrentFrame(cont); callback?.Invoke(cont); }); } else { yield return BuildCharacter(cs.CostumeName, cs.AnimationName, (go) => { var cont = go.GetComponent(); cont.PasteContainer(cs, new PoseLoadOptions(true)); cont.DeserializeFrames(cs); TimelineController.SetCurrentFrame(cont); callback?.Invoke(cont); }); } break; case KF3ObjectContainerSerializable cs: yield return SpawnFurniture(cs.Filename); break; } } public IEnumerator UpdateCharacter(KF3CharacterContainer container, string modelName, string animSetName, Action callback = null) { if (container.LoadInProgress) yield break; string mIdLong = modelName.Split('_', '.')[1]; string aIdLong = animSetName.Split('_', '.')[1]; container.ModelId = int.Parse(mIdLong); container.CostumeName = modelName; container.AnimationName = animSetName; var data = container.Serialize() as KF3CharacterContainerSerializable; Destroy(container); yield return SpawnSerialized(data, callback); } public void SpawnReference(Texture2D texture, System.Action callback = null) { //GameObject go = new GameObject(texture.name); //go.AddComponent().Init(go); //GameObject go1 = GameObject.CreatePrimitive(PrimitiveType.Plane); //go1.transform.SetParent(go.transform); //go1.Get().material.shader = Shader.Find("Unlit/Transparent Cutout"); //go1.Get().material.mainTexture = texture; //go1.transform.localScale = new Vector3((float)texture.width / 5000, 1, (float)texture.height / 5000); //callback?.Invoke(go); } public IEnumerator SpawnAsset(string text, System.Action callback) { KF3AssetBundle assetBundle = Main.Assets.Find(text); yield return Main.Assets.LoadAsset(assetBundle, (ab) => { var background = Instantiate(ab.LoadAsset(ab.GetAllAssetNames()[0])) as GameObject; ab.Unload(false); callback?.Invoke(background); }); } public IEnumerator SpawnFurniture(string bundleName, System.Action callback = null) { KF3AssetBundle assetBundle = Main.Assets.GetFurnitureBundle(bundleName); if(assetBundle != null) { yield return Main.Assets.LoadAsset(assetBundle, (ab) => { KF3StaticContainer containter = KF3StaticContainer.Create(ab); callback?.Invoke(containter.gameObject); }); } else { assetBundle = Main.Assets.GetMiscBundle(bundleName); if (assetBundle == null) assetBundle = assetBundle = Main.Assets.GetMiracleBundle(bundleName); if (assetBundle != null) { yield return Spawn(assetBundle); } } } public IEnumerator Spawn(KF3AssetBundle assetBundle, System.Action callback = null) { yield return Main.Assets.LoadAsset(assetBundle, (ab) => { GameObject go = Instantiate(ab.LoadAsset(ab.GetAllAssetNames()[0]) as GameObject); go.layer = 0; KF3StaticContainer containter = go.AddComponent(); //containter.oName = assetBundle.DisplayName; UIHandleProp.CreateAsChild(containter, go.transform); //containter.PauseAll(); //containter.BuildHierarchy(); ab.Unload(false); callback?.Invoke(go); }); } /// Clean Up, delete all model remains public void DeleteAnimation(KF3CharacterContainer container) { List destroyQueue = new List() { container.BodyAnimation.gameObject }; List nullable = new List() { container.BodySimpleAnimation }; if(container as KF3FriendContainer != null) { var container1 = (KF3FriendContainer)container; destroyQueue.Add(container1.EarsAnimation.gameObject); destroyQueue.Add(container1.TailAnimation.gameObject); nullable.Add(container1.EarsSimpleAnimation); nullable.Add(container1.TailSimpleAnimation); } for (int i = destroyQueue.Count - 1; i >= 0; i--) { Destroy(destroyQueue[i]); } for (int i = nullable.Count - 1; i >= 0; i--) { nullable[i] = null; } Resources.UnloadUnusedAssets(); System.GC.Collect(); } }