2024-04-22 06:00:51 +08:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
public class DanMachiCharacterContainer : DanMachiObjectContainer, IAnimated
|
|
|
|
{
|
|
|
|
public CharacterAsset Data;
|
|
|
|
public string AnimationSet;
|
|
|
|
public string Animation;
|
|
|
|
|
|
|
|
public MorphPanel MorphPanel;
|
|
|
|
public CharacterPanel CharacterPanel;
|
|
|
|
public List<AnimationClip> Animations;
|
|
|
|
private Animator _animator;
|
|
|
|
private AnimatorOverrideController _animatorController;
|
|
|
|
private Dictionary<HumanBodyBones, Transform> _humanBones = new Dictionary<HumanBodyBones, Transform>();
|
|
|
|
|
|
|
|
public override void Select()
|
|
|
|
{
|
|
|
|
if(MorphPanel != null)
|
|
|
|
{
|
|
|
|
MorphPanel.gameObject.SetActive(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void Deselect()
|
|
|
|
{
|
|
|
|
if (MorphPanel != null)
|
|
|
|
{
|
|
|
|
MorphPanel.gameObject.SetActive(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Build(CharacterAsset model)
|
|
|
|
{
|
|
|
|
Data = model;
|
|
|
|
var characterAsset = AssetBundle.LoadFromFile(model.FilePath);
|
|
|
|
var animationSets = DanMachiAssetLibrary.Instance.Animations.Where(a => a.Category == model.Category && a.Id == model.Id);
|
|
|
|
|
|
|
|
foreach (var go in characterAsset.LoadAllAssets<GameObject>())
|
|
|
|
{
|
|
|
|
Instantiate(go, transform);
|
|
|
|
}
|
|
|
|
characterAsset.Unload(false);
|
|
|
|
|
|
|
|
SetDefaultMaterials(transform);
|
|
|
|
|
|
|
|
Init();
|
|
|
|
|
|
|
|
var defaultAnimSet = animationSets.FirstOrDefault(a => a.Costume == "common");
|
|
|
|
LoadAnimationSet(defaultAnimSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Init()
|
|
|
|
{
|
|
|
|
_animator = GetComponentInChildren<Animator>();
|
|
|
|
_animator.applyRootMotion = false;
|
|
|
|
_animator.runtimeAnimatorController = _animatorController = Instantiate(SharedResources.Instance.GenericAnimatorController);
|
|
|
|
CreateMorphPanel();
|
|
|
|
CreateCharacterPanel();
|
|
|
|
SetBones();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void LoadAnimationSet(CharacterAsset animationSet)
|
|
|
|
{
|
|
|
|
if (animationSet != null)
|
|
|
|
{
|
|
|
|
AnimationSet = animationSet.Costume;
|
|
|
|
Animation = "";
|
|
|
|
var animationAsset = AssetBundle.LoadFromFile(animationSet.FilePath);
|
|
|
|
Animations = animationAsset.LoadAllAssets<AnimationClip>().ToList();
|
|
|
|
animationAsset.Unload(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void PlayAnimation(string clipName)
|
|
|
|
{
|
|
|
|
var anim = Animations.FirstOrDefault(a=>a.name == clipName);
|
|
|
|
PlayAnimation(anim);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void PlayAnimation(AnimationClip anim)
|
|
|
|
{
|
|
|
|
if(anim == null)
|
|
|
|
{
|
|
|
|
Animation = "";
|
|
|
|
_animator.enabled = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Animation = anim.name;
|
|
|
|
_animator.enabled = true;
|
|
|
|
_animatorController["Anim"] = anim;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void SetDefaultMaterials(Transform t)
|
|
|
|
{
|
|
|
|
List<Material> materials = new List<Material>();
|
|
|
|
foreach (var renderer in t.GetComponentsInChildren<Renderer>())
|
|
|
|
{
|
|
|
|
foreach (var material in renderer.sharedMaterials)
|
|
|
|
{
|
|
|
|
if (materials.Contains(material)) continue;
|
|
|
|
materials.Add(material);
|
2024-04-23 18:25:12 +08:00
|
|
|
material.shader = Shader.Find("DanMachiUnlit");
|
2024-04-22 06:00:51 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void SetBones()
|
|
|
|
{
|
|
|
|
var humanBones = new Dictionary<HumanBodyBones, Transform>();
|
|
|
|
var allBones = _animator.transform.GetComponentsInChildren<Transform>().ToDictionary(b=>b.name, b=>b);
|
2024-04-23 18:25:12 +08:00
|
|
|
humanBones.Add(HumanBodyBones.Hips, TryGet(allBones,"Hips"));
|
|
|
|
humanBones.Add(HumanBodyBones.Spine, TryGet(allBones,"Spine"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightUpperLeg, TryGet(allBones,"RightUpLeg"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightLowerLeg, TryGet(allBones,"RightLeg"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightFoot, TryGet(allBones,"RightFoot"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightToes, TryGet(allBones,"RightToeBase"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftUpperLeg, TryGet(allBones,"LeftUpLeg"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftLowerLeg, TryGet(allBones,"LeftLeg"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftFoot, TryGet(allBones,"LeftFoot"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftToes, TryGet(allBones,"LeftToeBase"));
|
|
|
|
humanBones.Add(HumanBodyBones.Chest, TryGet(allBones,"Spine1"));
|
|
|
|
humanBones.Add(HumanBodyBones.UpperChest, TryGet(allBones,"Spine2"));
|
|
|
|
humanBones.Add(HumanBodyBones.Neck, TryGet(allBones,"Neck"));
|
|
|
|
humanBones.Add(HumanBodyBones.Head, TryGet(allBones,"Head"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightShoulder, TryGet(allBones,"RightShoulder"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightUpperArm, TryGet(allBones,"RightArm"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightLowerArm, TryGet(allBones,"RightForeArm"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightHand, TryGet(allBones,"RightHand"));
|
2024-04-22 06:00:51 +08:00
|
|
|
humanBones.Add(HumanBodyBones.RightIndexProximal, TryGet(allBones,"RightHandIndex1"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightIndexIntermediate, TryGet(allBones,"RightHandIndex2"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightMiddleProximal, TryGet(allBones,"RightHandMiddle1"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightMiddleIntermediate, TryGet(allBones,"RightHandMiddle2"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightRingProximal, TryGet(allBones,"RightHandRing1"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightRingIntermediate, TryGet(allBones,"RightHandRing2"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightLittleProximal, TryGet(allBones,"RightHandPinky1"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightLittleIntermediate, TryGet(allBones,"RightHandPinky2"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightThumbProximal, TryGet(allBones,"RightHandThumb1"));
|
|
|
|
humanBones.Add(HumanBodyBones.RightThumbIntermediate, TryGet(allBones,"RightHandThumb2"));
|
2024-04-23 18:25:12 +08:00
|
|
|
humanBones.Add(HumanBodyBones.LeftShoulder, TryGet(allBones,"LeftShoulder"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftUpperArm, TryGet(allBones,"LeftArm"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftLowerArm, TryGet(allBones,"LeftForeArm"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftHand, TryGet(allBones,"LeftHand"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftIndexProximal, TryGet(allBones,"LeftHandIndex1"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftIndexIntermediate, TryGet(allBones,"LeftHandIndex2"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftMiddleProximal, TryGet(allBones,"LeftHandMiddle1"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftMiddleIntermediate, TryGet(allBones,"LeftHandMiddle2"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftRingProximal, TryGet(allBones,"LeftHandRing1"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftRingIntermediate, TryGet(allBones,"LeftHandRing2"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftLittleProximal, TryGet(allBones,"LeftHandPinky1"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftLittleIntermediate, TryGet(allBones,"LeftHandPinky2"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftThumbProximal, TryGet(allBones,"LeftHandThumb1"));
|
|
|
|
humanBones.Add(HumanBodyBones.LeftThumbIntermediate, TryGet(allBones,"LeftHandThumb2"));
|
2024-04-22 06:00:51 +08:00
|
|
|
foreach(var bone in humanBones)
|
|
|
|
{
|
|
|
|
if(bone.Value != null)
|
|
|
|
{
|
|
|
|
var tags = new List<SerializableBone.BoneTags>() { SerializableBone.BoneTags.Humanoid };
|
|
|
|
if (bone.Value.name.Contains("Left"))
|
|
|
|
{
|
|
|
|
tags.Add(SerializableBone.BoneTags.Left);
|
|
|
|
}
|
|
|
|
else if (bone.Value.name.Contains("Right"))
|
|
|
|
{
|
|
|
|
tags.Add(SerializableBone.BoneTags.Right);
|
|
|
|
}
|
|
|
|
if((bone.Key >= HumanBodyBones.LeftThumbProximal && bone.Key <= HumanBodyBones.LeftLittleDistal)
|
|
|
|
|| (bone.Key >= HumanBodyBones.RightThumbProximal && bone.Key <= HumanBodyBones.RightLittleDistal))
|
|
|
|
{
|
|
|
|
tags.Add(SerializableBone.BoneTags.Finger);
|
|
|
|
}
|
2024-04-23 18:25:12 +08:00
|
|
|
UIHandle.CreateAsChild<UIHandleBone>(bone.Value).Init(this, tags).WithLineRenderer();
|
2024-04-22 06:00:51 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach(var bone in allBones.Values.Except(humanBones.Values))
|
|
|
|
{
|
|
|
|
var tags = new List<SerializableBone.BoneTags>();
|
|
|
|
if (bone.GetComponent<Unity.Animations.SpringBones.SpringBone>() != null)
|
|
|
|
{
|
|
|
|
tags.Add(SerializableBone.BoneTags.Dynamic);
|
|
|
|
}
|
2024-04-23 18:25:12 +08:00
|
|
|
UIHandle.CreateAsChild<UIHandleBone>(bone).Init(this, tags).WithLineRenderer();
|
2024-04-22 06:00:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_humanBones = humanBones;
|
|
|
|
}
|
|
|
|
|
|
|
|
public T TryGet<T>(Dictionary<string, T> dict, string key)
|
|
|
|
{
|
|
|
|
if (dict.ContainsKey(key))
|
|
|
|
{
|
|
|
|
return dict[key];
|
|
|
|
}
|
|
|
|
return default(T);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void CreateMorphPanel()
|
|
|
|
{
|
|
|
|
if(MorphPanel != null)
|
|
|
|
{
|
|
|
|
Destroy(MorphPanel.gameObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
var morphRenderers = new Dictionary<SkinnedMeshRenderer, List<MorphHelper>>();
|
|
|
|
foreach (var rend in gameObject.GetComponentsInChildren<SkinnedMeshRenderer>())
|
|
|
|
{
|
|
|
|
if(rend.sharedMesh.blendShapeCount > 0)
|
|
|
|
{
|
|
|
|
morphRenderers.Add(rend, new List<MorphHelper>());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (morphRenderers.Count == 0) return;
|
|
|
|
|
|
|
|
MorphPanel = MorphPanel.Create(morphRenderers.Select(mr=>mr.Key.sharedMesh.name).ToList());
|
|
|
|
MorphPanel.name = $"Chr_{Data.Id} Morphs";
|
|
|
|
|
|
|
|
foreach(var rend in morphRenderers)
|
|
|
|
{
|
|
|
|
var mesh = rend.Key.sharedMesh;
|
|
|
|
for(int i = 0; i < mesh.blendShapeCount; i++)
|
|
|
|
{
|
|
|
|
MorphPanel.CreateMorph(mesh.name, this, rend.Key, i, mesh.GetBlendShapeName(i).Replace("blendShape1.",""));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Morphs = morphRenderers;
|
|
|
|
DanMachiModelViewerInterface.Instance.SelectedObjectToolbar.AttachToThis(MorphPanel.GetComponent<UIElementDragger>());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void CreateCharacterPanel()
|
|
|
|
{
|
|
|
|
CharacterPanel = CharacterPanel.Create(this);
|
|
|
|
CharacterPanel.name = $"Chr_{Data.Id} Settings";
|
|
|
|
DanMachiModelViewerInterface.Instance.SelectedObjectToolbar.AttachToThis(CharacterPanel.GetComponent<UIElementDragger>());
|
|
|
|
}
|
|
|
|
|
|
|
|
public override Vector3 GetCenter()
|
|
|
|
{
|
|
|
|
if (_humanBones.ContainsKey(HumanBodyBones.Hips))
|
|
|
|
{
|
|
|
|
return _humanBones[HumanBodyBones.Hips].position;
|
|
|
|
}
|
|
|
|
return base.GetCenter();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override void OnDestroy()
|
|
|
|
{
|
|
|
|
if (_applicationQuitting) return;
|
|
|
|
if(MorphPanel != null)
|
|
|
|
{
|
|
|
|
Destroy(MorphPanel.gameObject);
|
|
|
|
}
|
|
|
|
Destroy(CharacterPanel.gameObject);
|
|
|
|
base.OnDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Animator GetAnimator()
|
|
|
|
{
|
|
|
|
return _animator;
|
|
|
|
}
|
|
|
|
}
|