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 Animations; private Animator _animator; private AnimatorOverrideController _animatorController; private Dictionary _humanBones = new Dictionary(); 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()) { 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.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().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 materials = new List(); foreach (var renderer in t.GetComponentsInChildren()) { foreach (var material in renderer.sharedMaterials) { if (materials.Contains(material)) continue; materials.Add(material); material.shader = Shader.Find("DanMachiUnlit"); } } } public void SetBones() { var humanBones = new Dictionary(); var allBones = _animator.transform.GetComponentsInChildren().ToDictionary(b=>b.name, b=>b); 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")); 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")); 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")); foreach(var bone in humanBones) { if(bone.Value != null) { var tags = new List() { 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); } UIHandle.CreateAsChild(bone.Value).Init(this, tags).WithLineRenderer(); } } foreach(var bone in allBones.Values.Except(humanBones.Values)) { var tags = new List(); if (bone.GetComponent() != null) { tags.Add(SerializableBone.BoneTags.Dynamic); } UIHandle.CreateAsChild(bone).Init(this, tags).WithLineRenderer(); } _humanBones = humanBones; } public T TryGet(Dictionary 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>(); foreach (var rend in gameObject.GetComponentsInChildren()) { if(rend.sharedMesh.blendShapeCount > 0) { morphRenderers.Add(rend, new List()); } } 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()); } public void CreateCharacterPanel() { CharacterPanel = CharacterPanel.Create(this); CharacterPanel.name = $"Chr_{Data.Id} Settings"; DanMachiModelViewerInterface.Instance.SelectedObjectToolbar.AttachToThis(CharacterPanel.GetComponent()); } 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; } }