Files
UmaViewer/Assets/Scripts/UmaContainer.cs
T
2022-09-12 22:34:08 +08:00

154 lines
4.8 KiB
C#

using Gallop;
using Newtonsoft.Json.Linq;
using RootMotion.Dynamics;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UmaContainer : MonoBehaviour
{
public JObject CharaData;
public GameObject Body;
public GameObject Tail;
public GameObject Head;
public GameObject PhysicsController;
public List<Texture2D> TailTextures = new List<Texture2D>();
public Animator UmaAnimator;
public AnimatorOverrideController OverrideController;
[Header("Face")]
public List<AnimationClip> FacialClips = new List<AnimationClip>();
public FaceDrivenKeyTarget FaceDrivenKeyTargets;
[Header("Generic")]
public bool IsGeneric = false;
public string VarCostumeIdShort, VarCostumeIdLong, VarSkin, VarHeight, VarSocks, VarBust;
public List<Texture2D> GenericBodyTextures = new List<Texture2D>();
[Header("Mini")]
public bool IsMini = false;
public List<Texture2D> MiniHeadTextures = new List<Texture2D>();
public static Transform FindBoneInChildren(Transform trans, string name)
{
foreach (Transform t in trans)
{
if (t.name == name)
{
return t;
}
else
{
Transform candidate = FindBoneInChildren(t, name);
if (candidate != null) return candidate;
}
}
return null;
}
public void OnDestroy()
{
if (TryGetComponent<PuppetMaster>(out PuppetMaster t))
{
Destroy(this);
}
else { Destroy(gameObject); }
}
public void MergeModel()
{
if (!Body) return;
List<Transform> bodybones = new List<Transform>(Body.GetComponentInChildren<SkinnedMeshRenderer>().bones);
List<Transform> emptyBones = new List<Transform>();
emptyBones.Add(Body.GetComponentInChildren<SkinnedMeshRenderer>().rootBone.Find("Tail_Ctrl"));
while (Body.transform.childCount > 0)
{
var child = Body.transform.GetChild(0);
child.SetParent(transform);
}
Destroy(Body);
//MergeHead
if (Head)
{
var headskins = Head.GetComponentsInChildren<SkinnedMeshRenderer>();
foreach (SkinnedMeshRenderer headskin in headskins)
{
emptyBones.AddRange(MergeBone(headskin, bodybones));
}
var eyes = new GameObject("Eyes");
eyes.transform.SetParent(transform);
while (Head.transform.childCount > 0)
{
var child = Head.transform.GetChild(0);
child.SetParent(child.name.Contains("info") ? eyes.transform : transform);
}
Destroy(Head);
}
//MergeTail
if (Tail)
{
var tailskin = Tail.GetComponentInChildren<SkinnedMeshRenderer>();
emptyBones.AddRange(MergeBone(tailskin, bodybones));
while (Tail.transform.childCount > 0)
{
var child = Tail.transform.GetChild(0);
child.SetParent(transform);
}
Destroy(Tail);
emptyBones.ForEach(a => { if (a) Destroy(a.gameObject); });
}
//MergeAvatar
UmaAnimator = gameObject.AddComponent<Animator>();
UmaAnimator.avatar = AvatarBuilder.BuildGenericAvatar(gameObject, gameObject.name);
UmaAnimator.runtimeAnimatorController = OverrideController = Instantiate(UmaViewerBuilder.Instance.OverrideController);
}
public Transform[] MergeBone(SkinnedMeshRenderer from, List<Transform> targetBones)
{
var rootbone = targetBones.FindLast(a => a.name.Equals(from.rootBone.name));
if (rootbone) from.rootBone = rootbone;
List<Transform> emptyBones = new List<Transform>();
Transform[] tmpBone = new Transform[from.bones.Length];
for (int i = 0; i < tmpBone.Length; i++)
{
var targetbone = targetBones.FindLast(a => a.name.Equals(from.bones[i].name));
if (targetbone)
{
tmpBone[i] = targetbone;
from.bones[i].position = targetbone.position;
while (from.bones[i].transform.childCount > 0)
{
from.bones[i].transform.GetChild(0).SetParent(targetbone);
}
emptyBones.Add(from.bones[i]);
}
else
{
tmpBone[i] = from.bones[i];
}
}
from.bones = tmpBone;
return emptyBones.ToArray() ;
}
public void LoadPhysics()
{
var springs = PhysicsController.GetComponentsInChildren<CySpringDataContainer>();
foreach (CySpringDataContainer spring in springs)
{
spring.InitializePhysics();
}
}
}