UniversalViewer/Assets/KF3/Scripts/KF3ModelBuilder.cs

198 lines
7.0 KiB
C#
Raw Normal View History

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<KF3ModelBuilder>();
private KF3ModelViewerMain Main => KF3ModelViewerMain.Instance;
public IEnumerator Init(Action<KF3ModelBuilder> callback)
{
callback(this);
yield break;
}
public IEnumerator BuildCharacter(string modelName, string animSetName, Action<GameObject> 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<GameObject> callback = null)
{
yield return KF3CeruleanContainer.CreateAsync(modelName, animSetName, (container) =>
{
Main.SelectObject(container);
callback?.Invoke(container.gameObject);
});
}
public override IEnumerator SpawnSerializedCoroutine(ObjectContainerSerializable oc, Action<ObjectContainer> callback = null)
{
return SpawnSerialized(oc as KF3ObjectContainerSerializable, callback);
}
public IEnumerator SpawnSerialized(KF3ObjectContainerSerializable oc, Action<ObjectContainer> 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<KF3CeruleanContainer>();
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<KF3FriendContainer>();
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<ObjectContainer> 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<GameObject> callback = null)
{
//GameObject go = new GameObject(texture.name);
//go.AddComponent<UIHandleReference>().Init(go);
//GameObject go1 = GameObject.CreatePrimitive(PrimitiveType.Plane);
//go1.transform.SetParent(go.transform);
//go1.Get<Renderer>().material.shader = Shader.Find("Unlit/Transparent Cutout");
//go1.Get<Renderer>().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<GameObject> 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<GameObject> 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<GameObject> 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<KF3StaticContainer>();
//containter.oName = assetBundle.DisplayName;
UIHandleProp.CreateAsChild(containter, go.transform);
//containter.PauseAll();
//containter.BuildHierarchy();
ab.Unload(false);
callback?.Invoke(go);
});
}
/// <summary> Clean Up, delete all model remains </summary>
public void DeleteAnimation(KF3CharacterContainer container)
{
List<GameObject> destroyQueue = new List<GameObject>()
{
container.BodyAnimation.gameObject
};
List<object> nullable = new List<object>()
{
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();
}
}