You've already forked UniversalViewer
DanMachi:
-compatibility improvements Core: -simplified object and keyframe serialization -complicated assetbundle loading
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,64 +1,77 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class DanMachiCharacterContainer : DanMachiObjectContainer, IAnimated
|
||||
public class DanMachiCharacterContainer : ObjectContainer, IAnimated
|
||||
{
|
||||
protected override System.Type _serializeType => typeof(DanMachiCharacterSerializable);
|
||||
protected override System.Type _keyframeType => typeof(DanMachiCharacterKeyframeData);
|
||||
|
||||
public CharacterAsset Data;
|
||||
public string AnimationSet;
|
||||
public string Animation;
|
||||
|
||||
public GameObject Body;
|
||||
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 List<Transform> Bones = new List<Transform>();
|
||||
|
||||
public override void Select()
|
||||
public void Init()
|
||||
{
|
||||
if(MorphPanel != null)
|
||||
_animator = GetComponentInChildren<Animator>();
|
||||
if(_animator != null)
|
||||
{
|
||||
MorphPanel.gameObject.SetActive(true);
|
||||
_animator.applyRootMotion = false;
|
||||
_animator.runtimeAnimatorController = _animatorController = Instantiate(SharedResources.Instance.GenericAnimatorController);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error.Log(Color.red, $"{name} has no animator");
|
||||
}
|
||||
CreateMorphPanel();
|
||||
CreateCharacterPanel();
|
||||
SetBones();
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
public void Rebuild(CharacterAsset model)
|
||||
{
|
||||
if (MorphPanel != null)
|
||||
{
|
||||
MorphPanel.gameObject.SetActive(false);
|
||||
}
|
||||
DestroyImmediate(Body);
|
||||
Build(model);
|
||||
}
|
||||
|
||||
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);
|
||||
var assetPath = Path.Combine(DanMachiAssetLibrary.Instance.LocalFilesPath, model.FilePath);
|
||||
var characterAsset = AssetLibrary.LoadFromFile(assetPath);
|
||||
var assetNames = characterAsset.GetAllAssetNames();
|
||||
var characterModel = assetNames.FirstOrDefault(a => Path.GetFileName(a).StartsWith("CP_") && a.EndsWith(".prefab"));
|
||||
|
||||
foreach (var go in characterAsset.LoadAllAssets<GameObject>())
|
||||
if(!string.IsNullOrEmpty(characterModel))
|
||||
{
|
||||
Instantiate(go, transform);
|
||||
Body = Instantiate(characterAsset.LoadAsset(characterModel), transform) as GameObject;
|
||||
}
|
||||
characterAsset.Unload(false);
|
||||
else
|
||||
{
|
||||
Body = new GameObject();
|
||||
Body.transform.SetParent(transform);
|
||||
foreach (var go in characterAsset.LoadAllAssets<GameObject>())
|
||||
{
|
||||
Instantiate(go, Body.transform);
|
||||
}
|
||||
}
|
||||
|
||||
LoadedAssets = new List<AssetBundleEntry>() { new AssetBundleEntry(model.AssetName, assetPath, characterAsset) };
|
||||
AssetLibrary.UnloadAsset(assetPath);
|
||||
|
||||
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)
|
||||
@@ -67,7 +80,7 @@ public class DanMachiCharacterContainer : DanMachiObjectContainer, IAnimated
|
||||
{
|
||||
AnimationSet = animationSet.Costume;
|
||||
Animation = "";
|
||||
var animationAsset = AssetBundle.LoadFromFile(animationSet.FilePath);
|
||||
var animationAsset = AssetBundle.LoadFromFile(Path.Combine(DanMachiAssetLibrary.Instance.LocalFilesPath, animationSet.FilePath));
|
||||
Animations = animationAsset.LoadAllAssets<AnimationClip>().ToList();
|
||||
animationAsset.Unload(false);
|
||||
}
|
||||
@@ -81,6 +94,12 @@ public class DanMachiCharacterContainer : DanMachiObjectContainer, IAnimated
|
||||
|
||||
public void PlayAnimation(AnimationClip anim)
|
||||
{
|
||||
if(_animator == null)
|
||||
{
|
||||
Error.Log(Color.red, $"{name} has no animator");
|
||||
return;
|
||||
}
|
||||
|
||||
if(anim == null)
|
||||
{
|
||||
Animation = "";
|
||||
@@ -110,8 +129,20 @@ public class DanMachiCharacterContainer : DanMachiObjectContainer, IAnimated
|
||||
|
||||
public void SetBones()
|
||||
{
|
||||
_humanBones.Clear();
|
||||
Bones.Clear();
|
||||
|
||||
if (_animator == null) return;
|
||||
|
||||
var humanBones = new Dictionary<HumanBodyBones, Transform>();
|
||||
var allBones = _animator.transform.GetComponentsInChildren<Transform>().ToDictionary(b=>b.name, b=>b);
|
||||
var allBones = new Dictionary<string, Transform>();
|
||||
foreach(var bone in _animator.transform.GetComponentsInChildren<Transform>())
|
||||
{
|
||||
if (!allBones.ContainsKey(bone.name))
|
||||
{
|
||||
allBones[bone.name] = bone;
|
||||
}
|
||||
}
|
||||
humanBones.Add(HumanBodyBones.Hips, TryGet(allBones,"Hips"));
|
||||
humanBones.Add(HumanBodyBones.Spine, TryGet(allBones,"Spine"));
|
||||
humanBones.Add(HumanBodyBones.RightUpperLeg, TryGet(allBones,"RightUpLeg"));
|
||||
@@ -186,6 +217,7 @@ public class DanMachiCharacterContainer : DanMachiObjectContainer, IAnimated
|
||||
}
|
||||
|
||||
_humanBones = humanBones;
|
||||
Bones = allBones.Values.ToList();
|
||||
}
|
||||
|
||||
public T TryGet<T>(Dictionary<string, T> dict, string key)
|
||||
@@ -199,11 +231,6 @@ public class DanMachiCharacterContainer : DanMachiObjectContainer, IAnimated
|
||||
|
||||
public void CreateMorphPanel()
|
||||
{
|
||||
if(MorphPanel != null)
|
||||
{
|
||||
Destroy(MorphPanel.gameObject);
|
||||
}
|
||||
|
||||
var morphRenderers = new Dictionary<SkinnedMeshRenderer, List<MorphHelper>>();
|
||||
foreach (var rend in gameObject.GetComponentsInChildren<SkinnedMeshRenderer>())
|
||||
{
|
||||
@@ -213,29 +240,59 @@ public class DanMachiCharacterContainer : DanMachiObjectContainer, IAnimated
|
||||
}
|
||||
}
|
||||
|
||||
if (morphRenderers.Count == 0) return;
|
||||
if (morphRenderers.Count == 0)
|
||||
{
|
||||
if(MorphPanel != null)
|
||||
{
|
||||
Destroy(MorphPanel.gameObject);
|
||||
MorphPanel = null;
|
||||
InstantiatedObjects.Remove(MorphPanel.gameObject);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
MorphPanel = MorphPanel.Create(morphRenderers.Select(mr=>mr.Key.sharedMesh.name).ToList());
|
||||
MorphPanel.name = $"Chr_{Data.Id} Morphs";
|
||||
if(MorphPanel != null)
|
||||
{
|
||||
MorphPanel.Init(morphRenderers.Select(mr => mr.Key.sharedMesh.name).ToList());
|
||||
}
|
||||
else
|
||||
{
|
||||
MorphPanel = MorphPanel.Create(morphRenderers.Select(mr => mr.Key.sharedMesh.name).ToList());
|
||||
MorphPanel.name = $"Chr_{Data.Id} Morphs";
|
||||
InstantiatedObjects.Add(MorphPanel.gameObject);
|
||||
DanMachiInterface.Instance.SelectedObjectToolbar.AttachToThis(MorphPanel.GetComponent<UIElementDragger>());
|
||||
}
|
||||
|
||||
foreach(var rend in morphRenderers)
|
||||
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.",""));
|
||||
var panel = MorphPanel.CreateMorph(mesh.name, this, rend.Key, i, mesh.GetBlendShapeName(i).Replace("blendShape1.",""));
|
||||
var helper = panel.MorphHelper;
|
||||
if (morphRenderers.ContainsKey(rend.Key))
|
||||
morphRenderers[rend.Key].Add(helper);
|
||||
else
|
||||
morphRenderers.Add(rend.Key, new List<MorphHelper>() { helper });
|
||||
}
|
||||
}
|
||||
|
||||
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>());
|
||||
if(CharacterPanel != null)
|
||||
{
|
||||
CharacterPanel.Init(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterPanel = CharacterPanel.Create(this);
|
||||
CharacterPanel.name = $"Chr_{Data.Id} Settings";
|
||||
InstantiatedObjects.Add(CharacterPanel.gameObject);
|
||||
DanMachiInterface.Instance.SelectedObjectToolbar.AttachToThis(CharacterPanel.GetComponent<UIElementDragger>());
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 GetCenter()
|
||||
@@ -247,19 +304,45 @@ public class DanMachiCharacterContainer : DanMachiObjectContainer, IAnimated
|
||||
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;
|
||||
}
|
||||
|
||||
public override void PastePose(KeyframeData frame, PoseLoadOptions pasteParams)
|
||||
{
|
||||
PlayAnimation("");
|
||||
|
||||
if (pasteParams.Root)
|
||||
{
|
||||
transform.SetTransform(frame.Root);
|
||||
}
|
||||
|
||||
var frameData = frame as DanMachiCharacterKeyframeData;
|
||||
if (frameData == null) return;
|
||||
|
||||
foreach (var bone in frameData.Bones.Bones)
|
||||
{
|
||||
var targetBone = Bones.FirstOrDefault(b => b.name == bone.Name);
|
||||
if (targetBone == null) continue;
|
||||
|
||||
bone.Transform.ApplyTo(targetBone.transform);
|
||||
}
|
||||
|
||||
foreach(var morph in frameData.Morphs)
|
||||
{
|
||||
var renderer = Morphs.Keys.FirstOrDefault(k => k.name == morph.Key);
|
||||
if (renderer == null) continue;
|
||||
|
||||
foreach(var value in morph.Value)
|
||||
{
|
||||
var helper = Morphs[renderer].FirstOrDefault(h => h.Name == value.Name);
|
||||
if (helper == null) continue;
|
||||
helper.Value = value.Value;
|
||||
helper.UpdateMorph(value.Strength);
|
||||
}
|
||||
}
|
||||
|
||||
SetKeyframe();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class DanMachiCharacterKeyframeData : KeyframeData
|
||||
{
|
||||
public BoneList Bones = new BoneList();
|
||||
public Dictionary<string, List<MorphHelper>> Morphs = new Dictionary<string, List<MorphHelper>>();
|
||||
|
||||
public DanMachiCharacterKeyframeData() { }
|
||||
|
||||
public DanMachiCharacterKeyframeData(DanMachiCharacterContainer container)
|
||||
{
|
||||
this.Root = new SerializableTransform(container.transform);
|
||||
this.Bones = new BoneList() { Name = "", Bones = container.Bones.Select(b => new SerializableBone(b)).ToArray() };
|
||||
this.Morphs = container.Morphs.ToDictionary(m => m.Key.name, m => m.Value);
|
||||
}
|
||||
|
||||
public override KeyframeData Clone()
|
||||
{
|
||||
var keyframe = new DanMachiCharacterKeyframeData();
|
||||
keyframe.Root = new SerializableTransform(this.Root);
|
||||
keyframe.Bones = new BoneList() { Name = Bones.Name, Bones = Bones.Bones.Select(b=> new SerializableBone(b)).ToArray() };
|
||||
keyframe.Morphs = Morphs.ToDictionary(m => m.Key, m => m.Value.Select(v=>new MorphHelper(v.ParentName, v.Name, v.Strength, v.Value)).ToList());
|
||||
return keyframe;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c58ee12edd81a8d43a9107bc7906a17b
|
||||
guid: d096ac3a0685dd54a836bc35192a0522
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
public class DanMachiCharacterSerializable : ObjectContainerSerializable
|
||||
{
|
||||
public string AssetName;
|
||||
|
||||
public DanMachiCharacterSerializable() { }
|
||||
|
||||
public DanMachiCharacterSerializable(DanMachiCharacterContainer container) : base(container)
|
||||
{
|
||||
AssetName = container.Data.AssetName;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ce5c34b04160214b935e3dcefed9ffc
|
||||
guid: 90e549cfb34f0cc47ac51d28cf4a6d9a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,42 +0,0 @@
|
||||
public class DanMachiObjectContainer : ObjectContainer
|
||||
{
|
||||
protected static DanMachiModelViewerMain Main => DanMachiModelViewerMain.Instance;
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
if (DoNotSave) return;
|
||||
|
||||
if(Frames.Count == 0)
|
||||
{
|
||||
SetKeyframe();
|
||||
}
|
||||
|
||||
DanMachiModelViewerMain.RegisterObject(this);
|
||||
var selector = UITimelineObjectEntry.Create(this);
|
||||
InstantiatedObjects.Add(selector.gameObject);
|
||||
|
||||
ModelViewerMain.GetInstance<DanMachiModelViewerMain>().SelectObject(this);
|
||||
}
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
if(_applicationQuitting) return;
|
||||
|
||||
if (Main.SelectedObject == this)
|
||||
{
|
||||
Main.SelectObject(null);
|
||||
}
|
||||
|
||||
ModelViewerMain.UnregisterObject(this);
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,8 @@ public class DanMachiAssetLibrary : AssetLibrary
|
||||
// ParseList(str);
|
||||
//});
|
||||
|
||||
string catalogPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "Low\\aiming\\DanChro\\com.unity.addressables\\catalog_0.0.0.json";
|
||||
string localFilesPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "Low\\Unity\\aiming_DanChro\\";
|
||||
string catalogPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "Low\\aiming\\DanChro\\com.unity.addressables\\catalog_0.0.0.json";
|
||||
LocalFilesPath = ModelViewerSettings.Get("AssetsPath", new ModelViewerSettings.Setting(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "Low\\Unity\\aiming_DanChro\\", ModelViewerSettings.SettingType.FolderPath));
|
||||
|
||||
yield return LoadAddressableCatalog(catalogPath);
|
||||
|
||||
@@ -49,13 +49,13 @@ public class DanMachiAssetLibrary : AssetLibrary
|
||||
if (entry.Contains("_anim_"))
|
||||
{
|
||||
AnimationAssets.Add(entry);
|
||||
var chara = new CharacterAsset(entry, localFilesPath + GetResourcePath(entry, out _));
|
||||
var chara = new CharacterAsset(entry, GetResourcePath(entry, out _));
|
||||
Animations.Add(chara);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterAssets.Add(entry);
|
||||
var chara = new CharacterAsset(entry, localFilesPath + GetResourcePath(entry, out _));
|
||||
var chara = new CharacterAsset(entry, GetResourcePath(entry, out _));
|
||||
Characters.Add(chara);
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public class DanMachiAssetLibrary : AssetLibrary
|
||||
// Characters.Add(chara);
|
||||
//}
|
||||
|
||||
DanMachiModelViewerInterface.Instance.CharacterSelection.SetData(Characters);
|
||||
DanMachiInterface.Instance.CharacterSelection.SetData(Characters);
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
6
Assets/DanMachi/Scripts/DanMachiInterface.cs
Normal file
6
Assets/DanMachi/Scripts/DanMachiInterface.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
public class DanMachiInterface : ModelViewerInterface
|
||||
{
|
||||
public static DanMachiInterface Instance => GetInstance<DanMachiInterface>();
|
||||
|
||||
public CharacterDropdown CharacterSelection;
|
||||
}
|
||||
42
Assets/DanMachi/Scripts/DanMachiMain.cs
Normal file
42
Assets/DanMachi/Scripts/DanMachiMain.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(DanMachiAssetLibrary), typeof(DanMachiModelBuilder), typeof(DanMachiInterface))]
|
||||
public class DanMachiMain : ModelViewerMain
|
||||
{
|
||||
public static DanMachiMain Instance => GetInstance<DanMachiMain>();
|
||||
|
||||
protected DanMachiAssetLibrary _assets => DanMachiAssetLibrary.Instance;
|
||||
protected DanMachiModelBuilder _modelBuilder => DanMachiModelBuilder.Instance;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
CurrentScene = SceneContainer.Create<SceneContainer>(this);
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
private IEnumerator Start()
|
||||
{
|
||||
Application.targetFrameRate = 30;
|
||||
Error.Log(Color.green, "Viewer version: " + Application.version);
|
||||
|
||||
float warningTimer = 0;
|
||||
while (DanMachiAssetLibrary.Instance == null || DanMachiModelBuilder.Instance == null || DanMachiInterface.Instance == null || SharedResources.Instance == null)
|
||||
{
|
||||
warningTimer += Time.deltaTime;
|
||||
if(warningTimer > 2)
|
||||
{
|
||||
warningTimer = 0;
|
||||
string report = $"AssetLibrary: {DanMachiAssetLibrary.Instance != null}\nModelBuilder: {DanMachiModelBuilder.Instance != null}\nInterface: {DanMachiInterface.Instance != null}\nResources: {SharedResources.Instance != null}";
|
||||
Error.Log(report, Color.red);
|
||||
}
|
||||
yield return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
//AutoSaveUpdate();
|
||||
}
|
||||
}
|
||||
@@ -8,28 +8,65 @@ public class DanMachiModelBuilder : ModelBuilder
|
||||
{
|
||||
public static DanMachiModelBuilder Instance => GetInstance<DanMachiModelBuilder>();
|
||||
|
||||
public override IEnumerator SpawnAsset(Enum assetType, string assetPath, Action<ObjectContainer> callback = null)
|
||||
public override IEnumerator SpawnSerializedCoroutine(ObjectContainerSerializable oc, Action<ObjectContainer> callback = null)
|
||||
{
|
||||
yield return base.SpawnSerializedCoroutine(oc);
|
||||
|
||||
switch (oc)
|
||||
{
|
||||
case DanMachiCharacterSerializable character:
|
||||
{
|
||||
var chara = SpawnAsset(AssetTypes.Character, character.AssetName);
|
||||
chara.DeserializeFrames(character);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Error.Log(Color.red, "Data not recognized: " + oc.Filename + " " + oc.GUID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
public override ObjectContainer SpawnAsset(Enum assetType, string assetPath)
|
||||
{
|
||||
base.SpawnAsset(assetType, assetPath);
|
||||
|
||||
switch (assetType)
|
||||
{
|
||||
case AssetTypes.Unknown:
|
||||
throw new NotImplementedException();
|
||||
case AssetTypes.Character:
|
||||
var asset = DanMachiAssetLibrary.Instance.Characters.First(c=>c.AssetName == assetPath);
|
||||
callback?.Invoke(SpawnCharacter(asset));
|
||||
break;
|
||||
return SpawnCharacter(asset);
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
public DanMachiCharacterContainer SpawnCharacter(CharacterAsset asset)
|
||||
private DanMachiCharacterContainer SpawnCharacter(CharacterAsset asset)
|
||||
{
|
||||
var container = ObjectContainer.Create<DanMachiCharacterContainer>("Character");
|
||||
var handle = UIHandle.CreateAsChild<UIHandleMain>(container.transform).Init(container);
|
||||
container.Build(asset);
|
||||
container.PlayAnimation(container.Animations[0]);
|
||||
|
||||
var animationSets = DanMachiAssetLibrary.Instance.Animations.Where(a => a.Category == asset.Category && a.Id == asset.Id);
|
||||
var defaultAnimSet = animationSets.FirstOrDefault(a => a.Costume == "common");
|
||||
defaultAnimSet ??= animationSets.FirstOrDefault();
|
||||
if (defaultAnimSet != null)
|
||||
{
|
||||
var animSetDropdown = container.CharacterPanel.AnimationSetDropdown;
|
||||
var option = animSetDropdown.options.FindIndex(d => d.text == defaultAnimSet.Costume);
|
||||
if (option != -1)
|
||||
{
|
||||
animSetDropdown.value = option;
|
||||
container.CharacterPanel.AnimationDropdown.value = 1;
|
||||
}
|
||||
}
|
||||
|
||||
DanMachiMain.Instance.SelectObject(container);
|
||||
|
||||
return container;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
|
||||
public class DanMachiModelViewerInterface : ModelViewerInterface
|
||||
{
|
||||
public static DanMachiModelViewerInterface Instance => GetInstance<DanMachiModelViewerInterface>();
|
||||
|
||||
public CharacterDropdown CharacterSelection;
|
||||
public UIToolbar SelectedObjectToolbar;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(DanMachiAssetLibrary), typeof(DanMachiModelBuilder), typeof(DanMachiModelViewerInterface))]
|
||||
public class DanMachiModelViewerMain : ModelViewerMain
|
||||
{
|
||||
public static DanMachiModelViewerMain Instance => GetInstance<DanMachiModelViewerMain>();
|
||||
|
||||
protected DanMachiAssetLibrary _assets => DanMachiAssetLibrary.Instance;
|
||||
protected DanMachiModelBuilder _modelBuilder => DanMachiModelBuilder.Instance;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
CurrentScene = SceneContainer.Create<DanMachiSceneContainer>(this);
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
private IEnumerator Start()
|
||||
{
|
||||
Application.targetFrameRate = 30;
|
||||
Error.Log(Color.green, "Viewer version: " + Application.version);
|
||||
|
||||
float warningTimer = 0;
|
||||
while (DanMachiAssetLibrary.Instance == null || DanMachiModelBuilder.Instance == null || DanMachiModelViewerInterface.Instance == null || SharedResources.Instance == null)
|
||||
{
|
||||
warningTimer += Time.deltaTime;
|
||||
if(warningTimer > 2)
|
||||
{
|
||||
warningTimer = 0;
|
||||
string report = $"AssetLibrary: {DanMachiAssetLibrary.Instance != null}\nModelBuilder: {DanMachiModelBuilder.Instance != null}\nInterface: {DanMachiModelViewerInterface.Instance != null}\nResources: {SharedResources.Instance != null}";
|
||||
Error.Log(report, Color.red);
|
||||
}
|
||||
yield return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
//AutoSaveUpdate();
|
||||
}
|
||||
|
||||
public static void RegisterObject(DanMachiObjectContainer container)
|
||||
{
|
||||
Instance.CurrentScene.AllObjects.Add(container);
|
||||
}
|
||||
|
||||
public static void UnregisterObject(DanMachiObjectContainer container)
|
||||
{
|
||||
Instance.CurrentScene.AllObjects.Remove(container);
|
||||
}
|
||||
|
||||
public static void DisposeOf(GameObject go)
|
||||
{
|
||||
if (go == null) return;
|
||||
var rends = go.GetComponentsInChildren<Renderer>();
|
||||
foreach (var rend in rends)
|
||||
{
|
||||
for (int i = rend.materials.Length - 1; i >= 0; i--)
|
||||
{
|
||||
Destroy(rend.materials[i]);
|
||||
}
|
||||
}
|
||||
Destroy(go);
|
||||
UnityEngine.Resources.UnloadUnusedAssets();
|
||||
System.GC.Collect();
|
||||
}
|
||||
|
||||
public IEnumerator LoadScene(DanMachiSceneSerializable bc)
|
||||
{
|
||||
EmptyScene<DanMachiSceneContainer>();
|
||||
|
||||
foreach (var c in bc.Objects)
|
||||
{
|
||||
if (c.GUID == "cameraOrbit")
|
||||
{
|
||||
MainCameraOrbit.DeserializeFrames(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return _modelBuilder.SpawnSerialized(c);
|
||||
}
|
||||
}
|
||||
bc.Timeline.Deserialize(TimelineController.Instance);
|
||||
CurrentScene.Frames = bc.Frames.Select(f => new FrameContent(f)).ToList();
|
||||
yield return 0;
|
||||
TimelineController.SetCurrentFrame(TimelineController.Instance.CurrentFrame);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class DanMachiSceneContainer : SceneContainer
|
||||
{
|
||||
public override KeyframeData SerializeFrame()
|
||||
{
|
||||
return new KeyframeData();
|
||||
}
|
||||
|
||||
public override ObjectContainerSerializable Serialize()
|
||||
{
|
||||
return new SceneSerializable(this);
|
||||
}
|
||||
|
||||
public override void Lerp(KeyframeData frame1, KeyframeData frame2, float amount)
|
||||
{
|
||||
var frame = (frame1 as KeyframeData).Lerp(frame2, amount) as KeyframeData;
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
if (_applicationQuitting) return;
|
||||
|
||||
for (int i = AllObjects.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var obj = AllObjects[i];
|
||||
if (obj.GetDataType() == DataType.Camera)
|
||||
{
|
||||
Debug.Log("Destroying cam");
|
||||
obj.Frames.Clear();
|
||||
obj.SetDefaultFrame();
|
||||
continue;
|
||||
}
|
||||
Destroy(obj.gameObject);
|
||||
}
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
//Settings.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
{
|
||||
//Settings.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
using System;
|
||||
|
||||
[Serializable]
|
||||
public class DanMachiSceneSerializable : SceneSerializable
|
||||
{
|
||||
}
|
||||
@@ -1,21 +1,8 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Animations.SpringBones
|
||||
{
|
||||
public class SpringBone : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Animations.SpringBones
|
||||
{
|
||||
public class SpringCapsuleCollider : MonoBehaviour
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c04af4c8b1b74df4783e6f4815bd909f
|
||||
guid: 572171c99ddfc0542b942432884ec564
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
8
Assets/DanMachi/Scripts/SpringBone/SpringManager.cs
Normal file
8
Assets/DanMachi/Scripts/SpringBone/SpringManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Animations.SpringBones
|
||||
{
|
||||
public class SpringManager : MonoBehaviour
|
||||
{
|
||||
}
|
||||
}
|
||||
11
Assets/DanMachi/Scripts/SpringBone/SpringManager.cs.meta
Normal file
11
Assets/DanMachi/Scripts/SpringBone/SpringManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eebc1635655c1984b999d5430c8d3ce0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Animations.SpringBones
|
||||
{
|
||||
public class SpringSphereCollider : MonoBehaviour
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a181323294f10e14faef8a3238a3bf5f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -60,32 +60,33 @@ public class CharacterDropdown : MonoBehaviour
|
||||
|
||||
UnityAction<int> groupCallback = (index) =>
|
||||
{
|
||||
if (index == 0) return;
|
||||
if (index == 0)
|
||||
{
|
||||
SetDropdownData(1, null);
|
||||
Despawn();
|
||||
return;
|
||||
}
|
||||
|
||||
var category = GetOption(0);
|
||||
SetDropdownData(1, characters.Where(c => c.Category == category).Select(c => c.Id).Distinct().ToList(), true, true);
|
||||
//SetDropdownData(2, new List<string>(), true, true);
|
||||
};
|
||||
|
||||
UnityAction<int> charaCallback = (index) =>
|
||||
{
|
||||
if (index == 0) return;
|
||||
if (index == 0)
|
||||
{
|
||||
Despawn();
|
||||
return;
|
||||
}
|
||||
|
||||
var category = GetOption(0);
|
||||
var id = GetOption(1);
|
||||
var costumes = characters.Where(c => c.Category == category && c.Id == id);
|
||||
var costume = costumes.FirstOrDefault(c => c.Costume == "common");
|
||||
costume ??= costumes.First();
|
||||
DanMachiModelBuilder.Instance.SpawnCharacter(costume);
|
||||
//SetDropdownData(2, characters.Where(c => c.Category == category && c.Id == id).Select(c => c.Costume).ToList(), true, true);
|
||||
DanMachiModelBuilder.Instance.SpawnAsset(AssetTypes.Character, costume.AssetName);
|
||||
};
|
||||
|
||||
//UnityAction<int> costumeCallback = (index) =>
|
||||
//{
|
||||
// var chara = DanMachiAssetLibrary.Instance.GetCharacter(GetOption(0), GetOption(1), GetOption(2));
|
||||
// StartCoroutine(DanMachiModelBuilder.Instance.SpawnAsset(AssetTypes.Character, chara));
|
||||
//};
|
||||
|
||||
SetCallbacks(new List<UnityAction<int>>()
|
||||
{
|
||||
groupCallback,
|
||||
@@ -113,7 +114,7 @@ public class CharacterDropdown : MonoBehaviour
|
||||
{
|
||||
Debug.LogError("Delete Current");
|
||||
}
|
||||
StartCoroutine(ModelBuilder.GetInstance().SpawnAsset(AssetTypes.Character, MainDropdown.options[selection].text));
|
||||
StartCoroutine(ModelBuilder.GetInstance().SpawnAssetCoroutine(AssetTypes.Character, MainDropdown.options[selection].text));
|
||||
}
|
||||
|
||||
public void SetDropdownData(string label, List<string> options, bool nullValue = false, bool sortValues = false)
|
||||
@@ -122,12 +123,6 @@ public class CharacterDropdown : MonoBehaviour
|
||||
SetDropdownData(depth, options, nullValue, sortValues);
|
||||
}
|
||||
|
||||
public string GetOption(int depth)
|
||||
{
|
||||
if (Dropdowns[depth].value == 0) return null;
|
||||
return Dropdowns[depth].options[Dropdowns[depth].value].text;
|
||||
}
|
||||
|
||||
public void SetDropdownData(int depth, List<string> options, bool nullValue = false, bool sortValues = false)
|
||||
{
|
||||
if (depth >= Dropdowns.Count || depth < 0)
|
||||
@@ -137,4 +132,42 @@ public class CharacterDropdown : MonoBehaviour
|
||||
}
|
||||
ModelViewerInterface.SetDropdownData(Dropdowns[depth], options, nullValue, sortValues);
|
||||
}
|
||||
|
||||
public void SelectDropdownData(int depth, string valueText, bool notify)
|
||||
{
|
||||
var dropdown = Dropdowns[depth];
|
||||
var value = dropdown.options.FindIndex(d=>d.text == valueText);
|
||||
SelectDropdownData(depth, value, notify);
|
||||
}
|
||||
|
||||
public void SelectDropdownData(int depth, int value, bool notify)
|
||||
{
|
||||
if (value == -1) return;
|
||||
|
||||
var dropdown = Dropdowns[depth];
|
||||
|
||||
if (notify)
|
||||
{
|
||||
dropdown.value = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
dropdown.SetValueWithoutNotify(value);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetOption(int depth)
|
||||
{
|
||||
if (Dropdowns[depth].value == 0) return null;
|
||||
return Dropdowns[depth].options[Dropdowns[depth].value].text;
|
||||
}
|
||||
|
||||
private void Despawn()
|
||||
{
|
||||
var selected = ModelViewerMain.GetInstance().SelectedObject;
|
||||
if (selected != null)
|
||||
{
|
||||
selected.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,10 @@ public class CharacterPanel : MonoBehaviour
|
||||
{
|
||||
var pose = _selectedChara.SerializeFrame();
|
||||
var data = _selectedChara.Data;
|
||||
var newData = DanMachiAssetLibrary.Instance.Characters.First(c => c.Category == data.Category && c.Id == data.Id && c.Costume == CostumeDropdown.options[value].text);
|
||||
var chara = DanMachiModelBuilder.Instance.SpawnCharacter(newData);
|
||||
chara.PastePose(pose, PoseLoadOptions.All());
|
||||
_selectedChara.Rebuild(DanMachiAssetLibrary.Instance.Characters.First(c => c.Category == data.Category && c.Id == data.Id && c.Costume == CostumeDropdown.options[value].text));
|
||||
//var newData = DanMachiAssetLibrary.Instance.Characters.First(c => c.Category == data.Category && c.Id == data.Id && c.Costume == CostumeDropdown.options[value].text);
|
||||
//var chara = DanMachiModelBuilder.Instance.SpawnAsset(AssetTypes.Character, newData.AssetName);
|
||||
_selectedChara.PastePose(pose, PoseLoadOptions.All());
|
||||
}
|
||||
|
||||
public void SelectAnimationSet(int value)
|
||||
@@ -38,6 +39,7 @@ public class CharacterPanel : MonoBehaviour
|
||||
if(value == 0)
|
||||
{
|
||||
AnimationDropdown.SetOptions(null);
|
||||
_selectedChara.PlayAnimation((AnimationClip)null);
|
||||
return;
|
||||
}
|
||||
var data = _selectedChara.Data;
|
||||
|
||||
Reference in New Issue
Block a user