AnimationLibrary Editor

AnimationLibraryBook editor setup.
AnimationLibrary texture2DArray generation and material setup.
This commit is contained in:
max
2020-12-10 19:51:02 +01:00
parent 52dd9d4b3c
commit e4ca15301b
18 changed files with 508 additions and 115 deletions

View File

@ -0,0 +1,86 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace TAO.VertexAnimation
{
[CreateAssetMenu(fileName = "new AnimationBook", menuName = "AnimationBook", order = 0)]
public class VA_AnimationBook : ScriptableObject
{
public int maxFrames;
public List<TextureGroup> textureGroups = new List<TextureGroup>() { new TextureGroup { shaderParamName = "_PositionMap", isLinear = false } };
public List<VA_AnimationPage> animationPages = new List<VA_AnimationPage>();
public Material[] materials;
public List<Texture2DArray> texture2DArray = null;
public void Create()
{
// Create textures.
texture2DArray.Clear();
foreach (var item in GetTextures())
{
if(VA_Texture2DArrayUtils.IsValidForTextureArray(item.Value.ToArray()))
{
texture2DArray.Add(VA_Texture2DArrayUtils.CreateTextureArray(item.Value.ToArray(), false, textureGroups[item.Key].isLinear, TextureWrapMode.Repeat, FilterMode.Point, 1, name + "-" + item.Key.ToString()));
}
}
// Assign material parameters.
if(materials != null)
{
foreach (Material mat in materials)
{
if(mat != null)
{
for (int i = 0; i < texture2DArray.Count; i++)
{
mat.SetTexture(textureGroups[i].shaderParamName, texture2DArray[i]);
}
}
}
}
}
private void OnValidate()
{
foreach (var item in GetTextures())
{
VA_Texture2DArrayUtils.IsValidForTextureArray(item.Value.ToArray());
}
}
private Dictionary<int, List<Texture2D>> GetTextures()
{
Dictionary<int, List<Texture2D>> dict = new Dictionary<int, List<Texture2D>>();
// Group and collect the textures.
for (int i = 0; i < textureGroups.Count; i++)
{
dict.Add(i, new List<Texture2D>());
for (int j = 0; j < animationPages.Count; j++)
{
dict[i].Add(animationPages[j].textures[i]);
}
}
return dict;
}
}
[System.Serializable]
public struct VA_AnimationPage
{
public string name;
public int frames;
public List<Texture2D> textures;
}
[System.Serializable]
public struct TextureGroup
{
public string shaderParamName;
public bool isLinear;
}
}

View File

@ -1,30 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace TAO.VertexAnimation
{
[CreateAssetMenu(fileName = "new AnimationBook", menuName = "AnimationBook", order = 0)]
public class VA_AnimationBookSO : ScriptableObject
{
public int maxFrames;
public Material[] materials;
public VA_AnimationPage[] animationPages;
private void Setup()
{
// TODO: ...
// GenerateTextures.
// SetupMaterials.
}
}
[System.Serializable]
public struct VA_AnimationPage
{
public string name;
public int frames;
public Texture2D texture2D;
}
}

View File

@ -1,38 +1,56 @@
using Unity.Entities;
using Unity.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace TAO.VertexAnimation
{
[System.Serializable]
public struct VA_AnimationData
[CreateAssetMenu(fileName = "new AnimationLibrary", menuName = "AnimationLibrary", order = 0)]
public class VA_AnimationLibrary : ScriptableObject
{
public FixedString32 name;
public int frames;
public int maxFrames;
// 1.0f / maxFrames.
public float frameTime;
// frameTime * frames.
public float duration;
}
public struct VA_AnimationLibrary
{
public BlobArray<VA_AnimationData> animations;
}
[SerializeField]
private VA_AnimationBook[] animationBooks;
public static class VA_AnimationLibraryUtils
{
public static int GetAnimation(ref VA_AnimationLibrary animationsRef, FixedString32 animationName)
[HideInInspector]
public List<VA_AnimationData> animations = null;
public void Create()
{
for (int i = 0; i < animationsRef.animations.Length; i++)
{
if (animationsRef.animations[i].name == animationName)
{
return i;
}
}
foreach (VA_AnimationBook book in animationBooks)
{
book.Create();
}
return -1;
}
ConvertAnimations();
}
private void OnValidate()
{
// TODO: Check for naming conflicts in AnimationBooks.
}
private void ConvertAnimations()
{
animations = new List<VA_AnimationData>();
if (animationBooks != null)
{
for (int b = 0; b < animationBooks.Length; b++)
{
if(animationBooks[b].animationPages != null)
{
for (int p = 0; p < animationBooks[b].animationPages.Count; p++)
{
animations.Add(new VA_AnimationData
{
name = new Unity.Collections.FixedString32(animationBooks[b].animationPages[p].name),
maxFrames = animationBooks[b].maxFrames,
frames = animationBooks[b].animationPages[p].frames,
frameTime = 1.0f / animationBooks[b].maxFrames,
duration = 1.0f / animationBooks[b].maxFrames * animationBooks[b].animationPages[p].frames
});
}
}
}
}
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 79884e6263d984c44af76267d129d76b
guid: 0d1625f26e651894b954faf1934378dc
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -7,7 +7,7 @@ namespace TAO.VertexAnimation
[UnityEngine.DisallowMultipleComponent]
public class VA_AnimationLibraryComponentAuthoring : UnityEngine.MonoBehaviour
{
public VA_AnimationLibrarySO animationLibrary;
public VA_AnimationLibrary animationLibrary;
}
public class VA_AnimationLibraryConversionSystem : GameObjectConversionSystem
@ -16,11 +16,14 @@ namespace TAO.VertexAnimation
{
Entities.ForEach((VA_AnimationLibraryComponentAuthoring animationLib) =>
{
animationLib.animationLibrary.Create();
// Blob builder to build.
using (BlobBuilder blobBuilder = new BlobBuilder(Allocator.Temp))
{
// Construct the root.
ref VA_AnimationLibrary animationDataBlobAsset = ref blobBuilder.ConstructRoot<VA_AnimationLibrary>();
ref VA_AnimationLibraryData animationDataBlobAsset = ref blobBuilder.ConstructRoot<VA_AnimationLibraryData>();
// Set all the data.
BlobBuilderArray<VA_AnimationData> animationDataArray = blobBuilder.Allocate(ref animationDataBlobAsset.animations, animationLib.animationLibrary.animations.Count);
@ -32,7 +35,7 @@ namespace TAO.VertexAnimation
}
// Construct blob asset reference.
BlobAssetReference<VA_AnimationLibrary> animLibAssetRef = blobBuilder.CreateBlobAssetReference<VA_AnimationLibrary>(Allocator.Persistent);
BlobAssetReference<VA_AnimationLibraryData> animLibAssetRef = blobBuilder.CreateBlobAssetReference<VA_AnimationLibraryData>(Allocator.Persistent);
// Add it to the asset store.
// TODO: Generate Hash based on Guid.

View File

@ -0,0 +1,38 @@
using Unity.Entities;
using Unity.Collections;
namespace TAO.VertexAnimation
{
[System.Serializable]
public struct VA_AnimationData
{
public FixedString32 name;
public int frames;
public int maxFrames;
// 1.0f / maxFrames.
public float frameTime;
// frameTime * frames.
public float duration;
}
public struct VA_AnimationLibraryData
{
public BlobArray<VA_AnimationData> animations;
}
public static class VA_AnimationLibraryUtils
{
public static int GetAnimation(ref VA_AnimationLibraryData animationsRef, FixedString32 animationName)
{
for (int i = 0; i < animationsRef.animations.Length; i++)
{
if (animationsRef.animations[i].name == animationName)
{
return i;
}
}
return -1;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 0d1625f26e651894b954faf1934378dc
guid: 79884e6263d984c44af76267d129d76b
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -1,46 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace TAO.VertexAnimation
{
[CreateAssetMenu(fileName = "new AnimationLibrary", menuName = "AnimationLibrary", order = 0)]
public class VA_AnimationLibrarySO : ScriptableObject
{
[SerializeField]
private VA_AnimationBookSO[] animationBooks;
[HideInInspector]
public List<VA_AnimationData> animations = null;
private void OnValidate()
{
SetupAnimations();
}
private void SetupAnimations()
{
animations = new List<VA_AnimationData>();
if (animationBooks != null)
{
for (int b = 0; b < animationBooks.Length; b++)
{
if(animationBooks[b].animationPages != null)
{
for (int p = 0; p < animationBooks[b].animationPages.Length; p++)
{
animations.Add(new VA_AnimationData
{
name = new Unity.Collections.FixedString32(animationBooks[b].animationPages[p].name),
maxFrames = animationBooks[b].maxFrames,
frames = animationBooks[b].animationPages[p].frames,
frameTime = 1.0f / animationBooks[b].maxFrames,
duration = 1.0f / animationBooks[b].maxFrames * animationBooks[b].animationPages[p].frames
});
}
}
}
}
}
}
}

View File

@ -17,7 +17,7 @@ namespace TAO.VertexAnimation
public int animationIndex;
public int animationIndexSchedule;
public float animationTime;
public BlobAssetReference<VA_AnimationLibrary> animationLibrary;
public BlobAssetReference<VA_AnimationLibraryData> animationLibrary;
}
[UpdateAfter(typeof(VA_AnimationLibraryConversionSystem))]
@ -25,7 +25,7 @@ namespace TAO.VertexAnimation
{
protected override void OnUpdate()
{
BlobAssetStore.TryGet(new Unity.Entities.Hash128("AnimationLib"), out BlobAssetReference<VA_AnimationLibrary> animLib);
BlobAssetStore.TryGet(new Unity.Entities.Hash128("AnimationLib"), out BlobAssetReference<VA_AnimationLibraryData> animLib);
Entities.ForEach((VA_AnimatorComponentAuthoring animator) =>
{

View File

@ -53,7 +53,7 @@ namespace TAO.VertexAnimation
Entities.ForEach((ref VA_AnimatorComponent ac) =>
{
// Get the animation lib data.
ref VA_AnimationLibrary animationsRef = ref ac.animationLibrary.Value;
ref VA_AnimationLibraryData animationsRef = ref ac.animationLibrary.Value;
ac.animationTime += deltaTime;
@ -74,7 +74,7 @@ namespace TAO.VertexAnimation
Entities.ForEach((Entity entity, ref VA_AnimatorComponent ac) =>
{
// Get the animation lib data.
ref VA_AnimationLibrary animationLib = ref ac.animationLibrary.Value;
ref VA_AnimationLibraryData animationLib = ref ac.animationLibrary.Value;
int animationIndex = VA_AnimationLibraryUtils.GetAnimation(ref animationLib, "Shoot");

View File

@ -0,0 +1,64 @@
using UnityEngine;
namespace TAO.VertexAnimation
{
public static class VA_Texture2DArrayUtils
{
public static Texture2DArray CreateTextureArray(Texture2D[] a_textures, bool a_useMipChain, bool a_isLinear,
TextureWrapMode a_wrapMode = TextureWrapMode.Repeat, FilterMode a_filterMode = FilterMode.Bilinear, int a_anisoLevel = 1, string a_name = "")
{
if(!IsValidForTextureArray(a_textures))
{
return null;
}
Texture2DArray textureArray = new Texture2DArray(a_textures[0].width, a_textures[0].height, a_textures.Length, a_textures[0].format, a_useMipChain, a_isLinear);
for (int i = 0; i < a_textures.Length; i++)
{
Graphics.CopyTexture(a_textures[i], 0, 0, textureArray, i, 0);
}
textureArray.wrapMode = a_wrapMode;
textureArray.filterMode = a_filterMode;
textureArray.anisoLevel = a_anisoLevel;
textureArray.name = a_name;
textureArray.Apply(false, false);
return textureArray;
}
public static bool IsValidForTextureArray(Texture2D[] a_textures)
{
if (a_textures == null || a_textures.Length <= 0)
{
Debug.LogError("No textures assigned!");
return false;
}
for (int i = 0; i < a_textures.Length; i++)
{
if (a_textures[i] == null)
{
Debug.LogError("Texture " + i.ToString() + " not assigned!");
return false;
}
if (a_textures[0].width != a_textures[i].width || a_textures[0].height != a_textures[i].height)
{
Debug.LogError("Texture " + a_textures[i].name + " has a different size!");
return false;
}
if (a_textures[0].format != a_textures[i].format || a_textures[0].graphicsFormat != a_textures[i].graphicsFormat)
{
Debug.LogError("Texture " + a_textures[i].name + " has a different format/graphics format!");
return false;
}
}
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85b760f664e13f84a940f7859bc9a684
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: