mirror of
https://github.com/maxartz15/VertexAnimation.git
synced 2024-12-05 01:30:44 +01:00
Simplify editor
Animations can now be used by scriptable object reference. Bake saves book and animations. Checks to update instead of create+overwrite assets to keep references/configuration.
This commit is contained in:
parent
2d6e920017
commit
c465ec6585
@ -20,6 +20,17 @@ namespace TAO.VertexAnimation.Editor
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryAddChildAsset(Object parent, Object child)
|
||||
{
|
||||
if (!HasChildAsset(parent, child))
|
||||
{
|
||||
AssetDatabase.AddObjectToAsset(child, parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void RemoveChildAssets(Object parent, Object[] filter = null)
|
||||
{
|
||||
var assets = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(parent));
|
||||
|
@ -1,7 +1,5 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TAO.VertexAnimation.Editor
|
||||
{
|
||||
@ -24,9 +22,6 @@ namespace TAO.VertexAnimation.Editor
|
||||
BakeGUI();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
EditorGUILayoutUtils.HorizontalLine(color: Color.gray);
|
||||
OutputGUI();
|
||||
}
|
||||
|
||||
private void InputGUI()
|
||||
@ -51,23 +46,25 @@ namespace TAO.VertexAnimation.Editor
|
||||
if (GUILayout.Button("Bake", GUILayout.Height(32)))
|
||||
{
|
||||
modelBaker.Bake();
|
||||
modelBaker.SaveAssets();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Delete", EditorStyles.miniButtonRight))
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Delete Assets", "Deleting assets will loose references within the project.", "Ok", "Cancel"))
|
||||
if (GUILayout.Button("Delete Unused Animations", EditorStyles.miniButtonLeft))
|
||||
{
|
||||
modelBaker.DeleteSavedAssets();
|
||||
if (EditorUtility.DisplayDialog("Delete Unused Animations", "Deleting assets will loose references within the project.", "Ok", "Cancel"))
|
||||
{
|
||||
modelBaker.DeleteUnusedAnimations();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OutputGUI()
|
||||
{
|
||||
using (new EditorGUI.DisabledGroupScope(true))
|
||||
{
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("bakedData"));
|
||||
if (GUILayout.Button("Delete", EditorStyles.miniButtonRight))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("Delete Assets", "Deleting assets will loose references within the project.", "Ok", "Cancel"))
|
||||
{
|
||||
modelBaker.DeleteSavedAssets();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,10 +29,6 @@ namespace TAO.VertexAnimation.Editor
|
||||
public VA_AnimationBook book = null;
|
||||
public List<VA_Animation> animations = new List<VA_Animation>();
|
||||
|
||||
// TODO: release baked data from memory when done.
|
||||
[SerializeField]
|
||||
private AnimationBaker.BakedData bakedData;
|
||||
|
||||
[System.Serializable]
|
||||
public class LODSettings
|
||||
{
|
||||
@ -89,15 +85,17 @@ namespace TAO.VertexAnimation.Editor
|
||||
target.name = model.name;
|
||||
|
||||
target.ConbineAndConvertGameObject();
|
||||
bakedData = target.Bake(animationClips, fps, textureWidth);
|
||||
AnimationBaker.BakedData bakedData = target.Bake(animationClips, fps, textureWidth);
|
||||
|
||||
positionMap = VA_Texture2DArrayUtils.CreateTextureArray(bakedData.positionMaps.ToArray(), false, true, TextureWrapMode.Repeat, FilterMode.Point, 1, string.Format("{0}_PositionMap", name), true);
|
||||
meshes = bakedData.mesh.GenerateLOD(lodSettings.LODCount(), lodSettings.GetQualitySettings());
|
||||
|
||||
DestroyImmediate(target);
|
||||
|
||||
SaveAssets(bakedData);
|
||||
}
|
||||
|
||||
public void SaveAssets()
|
||||
private void SaveAssets(AnimationBaker.BakedData bakedData)
|
||||
{
|
||||
AssetDatabaseUtils.RemoveChildAssets(this, new Object[2] { book, material });
|
||||
|
||||
@ -112,45 +110,19 @@ namespace TAO.VertexAnimation.Editor
|
||||
|
||||
if (generatePrefab)
|
||||
{
|
||||
GeneratePrefab();
|
||||
GeneratePrefab(bakedData);
|
||||
}
|
||||
|
||||
if (generateAnimationBook)
|
||||
{
|
||||
GenerateBook();
|
||||
GenerateBook(bakedData);
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
public void DeleteSavedAssets()
|
||||
{
|
||||
// Remove assets.
|
||||
var assets = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(this));
|
||||
foreach (var a in assets)
|
||||
{
|
||||
if (a != this)
|
||||
{
|
||||
AssetDatabase.RemoveObjectFromAsset(a);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete prefab.
|
||||
string path = AssetDatabase.GetAssetPath(prefab);
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
|
||||
// Clear variables.
|
||||
prefab = null;
|
||||
material = null;
|
||||
meshes = null;
|
||||
book = null;
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private void GeneratePrefab()
|
||||
private void GeneratePrefab(AnimationBaker.BakedData bakedData)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath(this);
|
||||
int start = path.LastIndexOf('/');
|
||||
@ -175,8 +147,9 @@ namespace TAO.VertexAnimation.Editor
|
||||
prefab = AnimationPrefab.Create(path, name, meshes, material, lodSettings.GetTransitionSettings());
|
||||
}
|
||||
|
||||
private void GenerateBook()
|
||||
private void GenerateBook(AnimationBaker.BakedData bakedData)
|
||||
{
|
||||
// Create book.
|
||||
if (!book)
|
||||
{
|
||||
book = CreateInstance<VA_AnimationBook>();
|
||||
@ -184,26 +157,29 @@ namespace TAO.VertexAnimation.Editor
|
||||
|
||||
book.name = string.Format("{0}_Book", name);
|
||||
book.positionMap = positionMap;
|
||||
book.animations = new List<VA_Animation>();
|
||||
book.TryAddMaterial(material);
|
||||
|
||||
// Save book.
|
||||
if (!AssetDatabaseUtils.HasChildAsset(this, book))
|
||||
{
|
||||
AssetDatabase.AddObjectToAsset(book, this);
|
||||
}
|
||||
|
||||
// Add animations.
|
||||
List<NamingConventionUtils.TextureInfo> info = new List<NamingConventionUtils.TextureInfo>();
|
||||
|
||||
// Get animation info.
|
||||
List<NamingConventionUtils.PositionMapInfo> info = new List<NamingConventionUtils.PositionMapInfo>();
|
||||
foreach (var t in bakedData.positionMaps)
|
||||
{
|
||||
info.Add(t.name.GetTextureInfo());
|
||||
}
|
||||
|
||||
// Create animations.
|
||||
for (int i = 0; i < info.Count; i++)
|
||||
{
|
||||
string animationName = string.Format("{0}_{1}", name, info[i].name);
|
||||
VA_AnimationData newData = new VA_AnimationData(animationName, info[i].frames, info[i].maxFrames, info[i].fps, i, -1);
|
||||
|
||||
|
||||
// Either update existing animation or create a new one.
|
||||
if (TryGetAnimationWithName(animationName, out VA_Animation animation))
|
||||
{
|
||||
animation.SetData(newData);
|
||||
@ -217,30 +193,82 @@ namespace TAO.VertexAnimation.Editor
|
||||
}
|
||||
|
||||
book.TryAddAnimation(animation);
|
||||
|
||||
if (!AssetDatabaseUtils.HasChildAsset(book, animation))
|
||||
{
|
||||
AssetDatabase.AddObjectToAsset(animation, book);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove unused animations.
|
||||
// Save animation objects.
|
||||
foreach (var a in animations)
|
||||
{
|
||||
AssetDatabaseUtils.TryAddChildAsset(book, a);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryGetAnimationWithName(string name, out VA_Animation animation)
|
||||
{
|
||||
foreach (var a in animations)
|
||||
{
|
||||
if (a.name == name)
|
||||
if (a != null)
|
||||
{
|
||||
animation = a;
|
||||
return true;
|
||||
if (a.name == name)
|
||||
{
|
||||
animation = a;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
animation = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void DeleteSavedAssets()
|
||||
{
|
||||
// Remove assets.
|
||||
var assets = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(this));
|
||||
foreach (var a in assets)
|
||||
{
|
||||
if (a != this)
|
||||
{
|
||||
AssetDatabase.RemoveObjectFromAsset(a);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete prefab.
|
||||
string path = AssetDatabase.GetAssetPath(prefab);
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
|
||||
// Clear variables.
|
||||
prefab = null;
|
||||
positionMap = null;
|
||||
material = null;
|
||||
meshes = null;
|
||||
book = null;
|
||||
animations = new List<VA_Animation>();
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
public void DeleteUnusedAnimations()
|
||||
{
|
||||
if (book != null)
|
||||
{
|
||||
// Remove unused animations.
|
||||
for (int i = 0; i < animations.Count; i++)
|
||||
{
|
||||
if (!book.animations.Contains(animations[i]))
|
||||
{
|
||||
AssetDatabase.RemoveObjectFromAsset(animations[i]);
|
||||
animations[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove zero entries.
|
||||
animations.RemoveAll(a => a == null);
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ namespace TAO.VertexAnimation
|
||||
{
|
||||
public static class NamingConventionUtils
|
||||
{
|
||||
public struct TextureInfo
|
||||
public struct PositionMapInfo
|
||||
{
|
||||
public string name;
|
||||
public int frames;
|
||||
@ -14,9 +14,9 @@ namespace TAO.VertexAnimation
|
||||
public int fps;
|
||||
}
|
||||
|
||||
public static TextureInfo GetTextureInfo(this string name)
|
||||
public static PositionMapInfo GetTextureInfo(this string name)
|
||||
{
|
||||
TextureInfo textureInfo = new TextureInfo();
|
||||
PositionMapInfo textureInfo = new PositionMapInfo();
|
||||
|
||||
string[] parts = name.Split('_');
|
||||
foreach (var p in parts)
|
||||
|
@ -1,3 +1,4 @@
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TAO.VertexAnimation
|
||||
@ -26,5 +27,10 @@ namespace TAO.VertexAnimation
|
||||
a_data.name = this.name;
|
||||
Data = a_data;
|
||||
}
|
||||
|
||||
public FixedString32 GetName()
|
||||
{
|
||||
return Data.name;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,10 +21,7 @@ namespace TAO.VertexAnimation
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxFrames
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
public int MaxFrames { get; private set; } = 0;
|
||||
|
||||
public Texture2DArray positionMap = null;
|
||||
public List<VA_Animation> animations = new List<VA_Animation>();
|
||||
@ -34,9 +31,10 @@ namespace TAO.VertexAnimation
|
||||
{
|
||||
if (animations != null && animations.Count != 0)
|
||||
{
|
||||
if (!animations.Contains(animation) && animation.Data.maxFrames == MaxFrames)
|
||||
if (!animations.Contains(animation))
|
||||
{
|
||||
animations.Add(animation);
|
||||
OnValidate();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -45,7 +43,7 @@ namespace TAO.VertexAnimation
|
||||
// Add first animation.
|
||||
animations.Add(animation);
|
||||
// Set maxFrames for this animation book.
|
||||
MaxFrames = animations[0].Data.maxFrames;
|
||||
OnValidate();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -67,16 +65,10 @@ namespace TAO.VertexAnimation
|
||||
return false;
|
||||
}
|
||||
|
||||
public void RemoveAnimation(VA_Animation animation)
|
||||
public void UpdateMaterials()
|
||||
{
|
||||
if (animations != null)
|
||||
{
|
||||
animations.Remove(animation);
|
||||
}
|
||||
}
|
||||
OnValidate();
|
||||
|
||||
public void SetMaterials()
|
||||
{
|
||||
if (materials != null)
|
||||
{
|
||||
foreach (var mat in materials)
|
||||
@ -97,8 +89,21 @@ namespace TAO.VertexAnimation
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMaxFrames()
|
||||
{
|
||||
if (animations != null && animations.Count != 0)
|
||||
{
|
||||
if (animations[0] != null)
|
||||
{
|
||||
MaxFrames = animations[0].Data.maxFrames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
UpdateMaxFrames();
|
||||
|
||||
if (animations != null)
|
||||
{
|
||||
foreach (var a in animations)
|
||||
@ -115,7 +120,7 @@ namespace TAO.VertexAnimation
|
||||
|
||||
if (positionMap != null)
|
||||
{
|
||||
if (positionMap.depth > animations.Count)
|
||||
if (positionMap.depth < animations.Count)
|
||||
{
|
||||
Debug.LogWarning(string.Format("More animations ({0}) than positionMaps in {1}!", animations.Count, this.name));
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Unity.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TAO.VertexAnimation
|
||||
@ -12,24 +13,58 @@ namespace TAO.VertexAnimation
|
||||
[HideInInspector]
|
||||
public List<VA_AnimationData> animationData = null;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[SerializeField]
|
||||
private List<VA_Animation> loadedAnimationsPreview = null;
|
||||
#endif
|
||||
|
||||
public void Init()
|
||||
{
|
||||
animationData = new List<VA_AnimationData>();
|
||||
|
||||
foreach (VA_AnimationBook book in animationBooks)
|
||||
{
|
||||
book.SetMaterials();
|
||||
book.UpdateMaterials();
|
||||
|
||||
foreach (VA_Animation animation in book.animations)
|
||||
if (book != null)
|
||||
{
|
||||
animationData.Add(animation.Data);
|
||||
foreach (VA_Animation animation in book.animations)
|
||||
{
|
||||
animationData.Add(animation.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
// TODO: Check for naming conflicts in AnimationBooks.
|
||||
Dictionary<string, VA_Animation> usedNames = new Dictionary<string, VA_Animation>();
|
||||
|
||||
foreach (VA_AnimationBook book in animationBooks)
|
||||
{
|
||||
if (book != null)
|
||||
{
|
||||
foreach (VA_Animation animation in book.animations)
|
||||
{
|
||||
if (!usedNames.ContainsKey(animation.name))
|
||||
{
|
||||
usedNames.Add(animation.name, animation);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning(string.Format("Naming conflict found in {0} - Animation {1} and {2} have the same name!", name, usedNames[animation.name].name, animation.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
loadedAnimationsPreview = new List<VA_Animation>();
|
||||
foreach (var un in usedNames)
|
||||
{
|
||||
loadedAnimationsPreview.Add(un.Value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user