瀏覽代碼

添加gpu动画

DESKTOP-FB72PO8\Administrator 7 月之前
父節點
當前提交
0225149c32
共有 100 個文件被更改,包括 4087 次插入105 次删除
  1. 196 104
      Assembly-CSharp.csproj
  2. 8 0
      Assets/Art/ArtHero/BakedAssets_Guaiwu01.meta
  3. 50 0
      Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_AnimationMatricesTexture_Snakelet.asset
  4. 8 0
      Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_AnimationMatricesTexture_Snakelet.asset.meta
  5. 218 0
      Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_GpuEcsAnimator.prefab
  6. 7 0
      Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_GpuEcsAnimator.prefab.meta
  7. 148 0
      Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_Material_Snakelet.mat
  8. 8 0
      Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_Material_Snakelet.mat.meta
  9. 358 0
      Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_Mesh_Snakelet.mesh
  10. 8 0
      Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_Mesh_Snakelet.mesh.meta
  11. 150 1
      Assets/Art/ArtHero/Guaiwu01.prefab
  12. 203 0
      Assets/Art/ArtHero/Guaiwu01_gpu.prefab
  13. 7 0
      Assets/Art/ArtHero/Guaiwu01_gpu.prefab.meta
  14. 246 0
      Assets/Art/ArtHero/New Animator Controller.controller
  15. 8 0
      Assets/Art/ArtHero/New Animator Controller.controller.meta
  16. 8 0
      Assets/GPUECSAnimationBaker.meta
  17. 8 0
      Assets/GPUECSAnimationBaker/Engine.meta
  18. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem.meta
  19. 37 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshBehaviour.cs
  20. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshBehaviour.cs.meta
  21. 24 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshComponents.cs
  22. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshComponents.cs.meta
  23. 40 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshSystem.cs
  24. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshSystem.cs.meta
  25. 18 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimationData.cs
  26. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimationData.cs.meta
  27. 41 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorAspect.cs
  28. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorAspect.cs.meta
  29. 123 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorBehaviour.cs
  30. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorBehaviour.cs.meta
  31. 69 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorComponents.cs
  32. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorComponents.cs.meta
  33. 30 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorControlComponents.cs
  34. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorControlComponents.cs.meta
  35. 26 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorInitializerBehaviour.cs
  36. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorInitializerBehaviour.cs.meta
  37. 313 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorSystem.cs
  38. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorSystem.cs.meta
  39. 12 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentAnchorData.cs
  40. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentAnchorData.cs.meta
  41. 37 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentBehaviour.cs
  42. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentBehaviour.cs.meta
  43. 10 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentComponents.cs
  44. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentComponents.cs.meta
  45. 25 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentInitializerBehaviour.cs
  46. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentInitializerBehaviour.cs.meta
  47. 43 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentSystem.cs
  48. 3 0
      Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentSystem.cs.meta
  49. 3 0
      Assets/GPUECSAnimationBaker/Engine/Baker.meta
  50. 832 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakeServices.cs
  51. 3 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakeServices.cs.meta
  52. 31 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerBehaviour.cs
  53. 11 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerBehaviour.cs.meta
  54. 79 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerEditor.cs
  55. 3 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerEditor.cs.meta
  56. 22 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerMenu.cs
  57. 3 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerMenu.cs.meta
  58. 12 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationEventBakerBehaviour.cs
  59. 3 0
      Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationEventBakerBehaviour.cs.meta
  60. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data.meta
  61. 25 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimationData.cs
  62. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimationData.cs.meta
  63. 94 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimationDataDrawer.cs
  64. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimationDataDrawer.cs.meta
  65. 10 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimationMatricesTexture.cs
  66. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimationMatricesTexture.cs.meta
  67. 8 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimationTypes.cs
  68. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimationTypes.cs.meta
  69. 15 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameter.cs
  70. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameter.cs.meta
  71. 41 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameterDrawer.cs
  72. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameterDrawer.cs.meta
  73. 9 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameterTypes.cs
  74. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameterTypes.cs.meta
  75. 11 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorState.cs
  76. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorState.cs.meta
  77. 31 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorStateDrawer.cs
  78. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AnimatorStateDrawer.cs.meta
  79. 14 0
      Assets/GPUECSAnimationBaker/Engine/Data/AttachmentAnchor.cs
  80. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AttachmentAnchor.cs.meta
  81. 29 0
      Assets/GPUECSAnimationBaker/Engine/Data/AttachmentAnchorDrawer.cs
  82. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/AttachmentAnchorDrawer.cs.meta
  83. 13 0
      Assets/GPUECSAnimationBaker/Engine/Data/BoneUsage.cs
  84. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/BoneUsage.cs.meta
  85. 14 0
      Assets/GPUECSAnimationBaker/Engine/Data/BoneUsagePerLoD.cs
  86. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/BoneUsagePerLoD.cs.meta
  87. 25 0
      Assets/GPUECSAnimationBaker/Engine/Data/BoneUsagePerLoDDrawer.cs
  88. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/BoneUsagePerLoDDrawer.cs.meta
  89. 26 0
      Assets/GPUECSAnimationBaker/Engine/Data/DualClipBlendData.cs
  90. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/DualClipBlendData.cs.meta
  91. 10 0
      Assets/GPUECSAnimationBaker/Engine/Data/EcsGpuMaterial.cs
  92. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/EcsGpuMaterial.cs.meta
  93. 7 0
      Assets/GPUECSAnimationBaker/Engine/Data/GlobalConstants.cs
  94. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/GlobalConstants.cs.meta
  95. 38 0
      Assets/GPUECSAnimationBaker/Engine/Data/GpuEcsAnimationBakerData.cs
  96. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/GpuEcsAnimationBakerData.cs.meta
  97. 55 0
      Assets/GPUECSAnimationBaker/Engine/Data/GpuEcsAnimationBakerDataDrawer.cs
  98. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/GpuEcsAnimationBakerDataDrawer.cs.meta
  99. 12 0
      Assets/GPUECSAnimationBaker/Engine/Data/SingleClipData.cs
  100. 3 0
      Assets/GPUECSAnimationBaker/Engine/Data/SingleClipData.cs.meta

+ 196 - 104
Assembly-CSharp.csproj

@@ -43,6 +43,18 @@
   <ItemGroup>
     <Analyzer Include="D:\tuanJieEditor\2022.3.38t2\Editor\Data\Tools\Unity.SourceGenerators\Unity.SourceGenerators.dll" />
     <Analyzer Include="D:\tuanJieEditor\2022.3.38t2\Editor\Data\Tools\Unity.SourceGenerators\Unity.Properties.SourceGenerator.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.SystemGenerator.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.SystemGenerator.SystemAPI.QueryBuilder.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.SystemGenerator.SystemAPI.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.Analyzer.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.SystemGenerator.LambdaJobs.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.SystemGenerator.Common.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.SystemGenerator.SystemAPI.Query.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.Analyzer.CodeFixes.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.AspectGenerator.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.Common.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.SystemGenerator.EntityQueryBulkOperations.dll" />
+    <Analyzer Include="D:\unityProject\XY001\Library\PackageCache\com.unity.entities@1.0.16\Unity.Entities\SourceGenerators\Unity.Entities.SourceGen.JobEntityGenerator.dll" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Assets\TextMesh Pro\Examples &amp; Extras\Scripts\TMP_TextEventHandler.cs" />
@@ -527,7 +539,7 @@
       <HintPath>D:\unityProject\XY001\Library\PackageCache\com.qq.weixin.minigame@3d141a9620\Runtime\Plugins\wx-perf.dll</HintPath>
     </Reference>
     <Reference Include="Unity.Collections.LowLevel.ILSupport">
-      <HintPath>D:\unityProject\XY001\Library\PackageCache\com.unity.collections@1.2.4\Unity.Collections.LowLevel.ILSupport\Unity.Collections.LowLevel.ILSupport.dll</HintPath>
+      <HintPath>D:\unityProject\XY001\Library\PackageCache\com.unity.collections@2.1.4\Unity.Collections.LowLevel.ILSupport\Unity.Collections.LowLevel.ILSupport.dll</HintPath>
     </Reference>
     <Reference Include="Unity.FontABTool">
       <HintPath>D:\unityProject\XY001\Library\PackageCache\com.qq.weixin.minigame@3d141a9620\Runtime\Plugins\Unity.FontABTool.dll</HintPath>
@@ -538,6 +550,9 @@
     <Reference Include="EPPlus">
       <HintPath>D:\unityProject\XY001\Assets\Scripts\ThirdParty\EPP\EPPlus.dll</HintPath>
     </Reference>
+    <Reference Include="Mono.Cecil">
+      <HintPath>D:\unityProject\XY001\Library\PackageCache\com.unity.nuget.mono-cecil@1.11.4\Mono.Cecil.dll</HintPath>
+    </Reference>
     <Reference Include="Unity.VisualScripting.Antlr3.Runtime">
       <HintPath>D:\unityProject\XY001\Library\PackageCache\com.unity.visualscripting@1.9.4\Runtime\VisualScripting.Flow\Dependencies\NCalc\Unity.VisualScripting.Antlr3.Runtime.dll</HintPath>
     </Reference>
@@ -907,35 +922,26 @@
     <Reference Include="System.Xml.Serialization">
       <HintPath>D:\tuanJieEditor\2022.3.38t2\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\System.Xml.Serialization.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.2D.IK.Runtime">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.IK.Runtime.dll</HintPath>
-    </Reference>
-    <Reference Include="Unity.RenderPipelines.Core.Runtime">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Core.Runtime.dll</HintPath>
-    </Reference>
     <Reference Include="Unity.Burst.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Burst.Editor.dll</HintPath>
     </Reference>
     <Reference Include="Unity.2D.Common.Path.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Common.Path.Editor.dll</HintPath>
     </Reference>
+    <Reference Include="Unity.ScriptableBuildPipeline">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.ScriptableBuildPipeline.dll</HintPath>
+    </Reference>
     <Reference Include="Wx">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Wx.dll</HintPath>
     </Reference>
     <Reference Include="WxEditor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\WxEditor.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.2D.PixelPerfect.Editor">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.PixelPerfect.Editor.dll</HintPath>
-    </Reference>
-    <Reference Include="Unity.Rider.Editor">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Rider.Editor.dll</HintPath>
-    </Reference>
     <Reference Include="Unity.2D.Aseprite.Common">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Aseprite.Common.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.2D.Sprite.Editor">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Sprite.Editor.dll</HintPath>
+    <Reference Include="Unity.Entities.Build">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.Build.dll</HintPath>
     </Reference>
     <Reference Include="Unity.RenderPipelines.Universal.Config.Runtime">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Universal.Config.Runtime.dll</HintPath>
@@ -946,14 +952,8 @@
     <Reference Include="Unity.RenderPipelines.Core.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Core.Editor.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.VisualScripting.Flow">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.VisualScripting.Flow.dll</HintPath>
-    </Reference>
-    <Reference Include="Unity.Mathematics.Editor">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Mathematics.Editor.dll</HintPath>
-    </Reference>
-    <Reference Include="Unity.2D.Tilemap.Extras.Editor">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Tilemap.Extras.Editor.dll</HintPath>
+    <Reference Include="Unity.Entities.UI.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.UI.Editor.dll</HintPath>
     </Reference>
     <Reference Include="Unity.RenderPipelines.Core.ShaderLibrary">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Core.ShaderLibrary.dll</HintPath>
@@ -961,8 +961,8 @@
     <Reference Include="Unity.Collections">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Collections.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.2D.SpriteShape.Runtime">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.SpriteShape.Runtime.dll</HintPath>
+    <Reference Include="Unity.Entities.Hybrid.HybridComponents">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.Hybrid.HybridComponents.dll</HintPath>
     </Reference>
     <Reference Include="Unity.2D.PixelPerfect">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.PixelPerfect.dll</HintPath>
@@ -970,6 +970,9 @@
     <Reference Include="PPv2URPConverters">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\PPv2URPConverters.dll</HintPath>
     </Reference>
+    <Reference Include="Unity.Deformations">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Deformations.dll</HintPath>
+    </Reference>
     <Reference Include="Unity.TextMeshPro">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.TextMeshPro.dll</HintPath>
     </Reference>
@@ -979,21 +982,114 @@
     <Reference Include="Unity.RenderPipelines.Universal.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Universal.Editor.dll</HintPath>
     </Reference>
+    <Reference Include="Unity.Mathematics.Extensions.Hybrid">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Mathematics.Extensions.Hybrid.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.RenderPipelines.Universal.Runtime">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Universal.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Burst">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Burst.dll</HintPath>
+    </Reference>
+    <Reference Include="UnityEditor.UI">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.2D.Animation.Runtime">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Animation.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.VisualScripting.Flow.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.VisualScripting.Flow.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.RenderPipeline.Universal.ShaderLibrary">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipeline.Universal.ShaderLibrary.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Serialization.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Serialization.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Transforms">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Transforms.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Serialization">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Serialization.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Scenes.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Scenes.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Entities.UI">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.UI.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Entities.Editor.Properties">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.Editor.Properties.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.RenderPipelines.Universal.Shaders">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Universal.Shaders.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Searcher.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Searcher.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.VisualScripting.State">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.VisualScripting.State.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Scenes">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Scenes.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.2D.SpriteShape.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.SpriteShape.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.ScriptableBuildPipeline.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.ScriptableBuildPipeline.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.2D.IK.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.IK.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.2D.IK.Runtime">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.IK.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.RenderPipelines.Core.Runtime">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Core.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Entities">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.2D.PixelPerfect.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.PixelPerfect.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Rider.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Rider.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.2D.Sprite.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Sprite.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Entities.Hybrid">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.Hybrid.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.VisualScripting.Flow">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.VisualScripting.Flow.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Mathematics.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Mathematics.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.2D.Tilemap.Extras.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Tilemap.Extras.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.2D.SpriteShape.Runtime">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.SpriteShape.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Collections.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Collections.Editor.dll</HintPath>
+    </Reference>
+    <Reference Include="Unity.Profiling.Core">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Profiling.Core.dll</HintPath>
+    </Reference>
     <Reference Include="Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll</HintPath>
     </Reference>
     <Reference Include="PsdPlugin">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\PsdPlugin.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.RenderPipelines.Universal.Runtime">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Universal.Runtime.dll</HintPath>
-    </Reference>
     <Reference Include="Unity.PlasticSCM.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.PlasticSCM.Editor.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.Burst">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Burst.dll</HintPath>
-    </Reference>
     <Reference Include="Unity.Timeline.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Timeline.Editor.dll</HintPath>
     </Reference>
@@ -1003,15 +1099,9 @@
     <Reference Include="Unity.ShaderGraph.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.ShaderGraph.Editor.dll</HintPath>
     </Reference>
-    <Reference Include="UnityEditor.UI">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\UnityEditor.UI.dll</HintPath>
-    </Reference>
     <Reference Include="Unity.VisualScripting.Core">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.VisualScripting.Core.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.2D.Animation.Runtime">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Animation.Runtime.dll</HintPath>
-    </Reference>
     <Reference Include="Unity.2D.Tilemap.Extras">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Tilemap.Extras.dll</HintPath>
     </Reference>
@@ -1021,24 +1111,27 @@
     <Reference Include="UnityEngine.UI">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\UnityEngine.UI.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.VisualScripting.Flow.Editor">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.VisualScripting.Flow.Editor.dll</HintPath>
+    <Reference Include="Unity.Entities.Graphics">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.Graphics.dll</HintPath>
     </Reference>
     <Reference Include="Unity.InternalAPIEngineBridge.001">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.InternalAPIEngineBridge.001.dll</HintPath>
     </Reference>
+    <Reference Include="Unity.Transforms.Hybrid">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Transforms.Hybrid.dll</HintPath>
+    </Reference>
     <Reference Include="Unity.2D.Common.Runtime">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Common.Runtime.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.RenderPipeline.Universal.ShaderLibrary">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipeline.Universal.ShaderLibrary.dll</HintPath>
-    </Reference>
     <Reference Include="Unity.Timeline">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Timeline.dll</HintPath>
     </Reference>
     <Reference Include="Unity.VisualScripting.SettingsProvider.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.VisualScripting.SettingsProvider.Editor.dll</HintPath>
     </Reference>
+    <Reference Include="Unity.Entities.Graphics.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.Graphics.Editor.dll</HintPath>
+    </Reference>
     <Reference Include="Unity.InternalAPIEditorBridge.001">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.InternalAPIEditorBridge.001.dll</HintPath>
     </Reference>
@@ -1054,56 +1147,27 @@
     <Reference Include="Unity.2D.Common.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Common.Editor.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.RenderPipelines.Universal.Shaders">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.RenderPipelines.Universal.Shaders.dll</HintPath>
-    </Reference>
     <Reference Include="Unity.TextMeshPro.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.TextMeshPro.Editor.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.Searcher.Editor">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Searcher.Editor.dll</HintPath>
-    </Reference>
-    <Reference Include="Unity.VisualScripting.State">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.VisualScripting.State.dll</HintPath>
+    <Reference Include="Unity.Mathematics.Extensions">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Mathematics.Extensions.dll</HintPath>
     </Reference>
     <Reference Include="Unity.2D.Tilemap.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Tilemap.Editor.dll</HintPath>
     </Reference>
+    <Reference Include="Unity.Entities.Editor">
+      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.Entities.Editor.dll</HintPath>
+    </Reference>
     <Reference Include="Unity.2D.Animation.Editor">
       <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.Animation.Editor.dll</HintPath>
     </Reference>
-    <Reference Include="Unity.2D.IK.Editor">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.IK.Editor.dll</HintPath>
-    </Reference>
-    <Reference Include="Unity.2D.SpriteShape.Editor">
-      <HintPath>D:\unityProject\XY001\Library\ScriptAssemblies\Unity.2D.SpriteShape.Editor.dll</HintPath>
-    </Reference>
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="UniRx.csproj">
-      <Project>{56f5be7b-33d9-e2a8-e913-507fd486ed71}</Project>
-      <Name>UniRx</Name>
-    </ProjectReference>
     <ProjectReference Include="Kybernetik.Animancer.FSM.csproj">
       <Project>{0ed4af61-7c5b-31d3-6459-8a6239a57f9a}</Project>
       <Name>Kybernetik.Animancer.FSM</Name>
     </ProjectReference>
-    <ProjectReference Include="Fort23.Core.csproj">
-      <Project>{445e7699-1039-047b-4806-470bcc01c6b3}</Project>
-      <Name>Fort23.Core</Name>
-    </ProjectReference>
-    <ProjectReference Include="NewAssembly.csproj">
-      <Project>{ef8f7edb-e142-c812-09c9-1efd42e75660}</Project>
-      <Name>NewAssembly</Name>
-    </ProjectReference>
-    <ProjectReference Include="Unity.AI.Navigation.csproj">
-      <Project>{6ec9c639-b54b-a18e-c822-0caa72f912e9}</Project>
-      <Name>Unity.AI.Navigation</Name>
-    </ProjectReference>
-    <ProjectReference Include="Kybernetik.Animancer.Editor.csproj">
-      <Project>{7ff57b24-3cdc-f1f3-965d-b7f88f25eba7}</Project>
-      <Name>Kybernetik.Animancer.Editor</Name>
-    </ProjectReference>
     <ProjectReference Include="StompyRobot.SRF.csproj">
       <Project>{6850a903-38e5-319b-70e9-1bbebfabf730}</Project>
       <Name>StompyRobot.SRF</Name>
@@ -1128,30 +1192,10 @@
       <Project>{fc3937b9-998a-f022-8329-db40273a9d7b}</Project>
       <Name>ThirdParty</Name>
     </ProjectReference>
-    <ProjectReference Include="Fort23.GameLogic.csproj">
-      <Project>{aa8b3008-7748-fe09-d0e8-e77da33c4943}</Project>
-      <Name>Fort23.GameLogic</Name>
-    </ProjectReference>
     <ProjectReference Include="Coffee.SoftMaskForUGUI.csproj">
       <Project>{1760b1d6-ee73-6a95-4a17-24bc21f6e8f8}</Project>
       <Name>Coffee.SoftMaskForUGUI</Name>
     </ProjectReference>
-    <ProjectReference Include="CodeStage.AFPSCounter.Editor.csproj">
-      <Project>{b2cf76b8-ee1d-c452-8c93-3c88f47c785b}</Project>
-      <Name>CodeStage.AFPSCounter.Editor</Name>
-    </ProjectReference>
-    <ProjectReference Include="Unity.AI.Navigation.Samples.csproj">
-      <Project>{c2199000-def0-facf-890c-7b0559fa37a3}</Project>
-      <Name>Unity.AI.Navigation.Samples</Name>
-    </ProjectReference>
-    <ProjectReference Include="Unity.AI.Navigation.Editor.ConversionSystem.csproj">
-      <Project>{f6528f8b-dbb4-84ed-ee55-12bcabff9780}</Project>
-      <Name>Unity.AI.Navigation.Editor.ConversionSystem</Name>
-    </ProjectReference>
-    <ProjectReference Include="CoreEditor.csproj">
-      <Project>{f10734e3-11fb-7644-3560-693b65970297}</Project>
-      <Name>CoreEditor</Name>
-    </ProjectReference>
     <ProjectReference Include="XNode.csproj">
       <Project>{27ef691a-f071-a1b3-5e1b-0e594da865c5}</Project>
       <Name>XNode</Name>
@@ -1168,6 +1212,10 @@
       <Project>{5f5b9cfa-a408-6622-a470-75aea4790283}</Project>
       <Name>GameTimeLine</Name>
     </ProjectReference>
+    <ProjectReference Include="GPUECSAnimationBakerSamples.csproj">
+      <Project>{df9a96d3-a901-392d-ea8d-d5bce0d75985}</Project>
+      <Name>GPUECSAnimationBakerSamples</Name>
+    </ProjectReference>
     <ProjectReference Include="Unity.AI.Navigation.Samples.Initialization.Editor.csproj">
       <Project>{220ede78-a995-1459-7c1e-d90e5cad0c9c}</Project>
       <Name>Unity.AI.Navigation.Samples.Initialization.Editor</Name>
@@ -1176,6 +1224,58 @@
       <Project>{4bd3b4ad-3b2c-a228-df65-5c58f3aacf30}</Project>
       <Name>StompyRobot.SRDebugger.Editor</Name>
     </ProjectReference>
+    <ProjectReference Include="CodeStage.AFPSCounter.Runtime.csproj">
+      <Project>{e69dd175-3705-64b7-6de3-d7bad627f6f5}</Project>
+      <Name>CodeStage.AFPSCounter.Runtime</Name>
+    </ProjectReference>
+    <ProjectReference Include="DownloadSystem.csproj">
+      <Project>{bcbcbf0b-c587-3257-d934-4f5bafbff086}</Project>
+      <Name>DownloadSystem</Name>
+    </ProjectReference>
+    <ProjectReference Include="UniRx.csproj">
+      <Project>{56f5be7b-33d9-e2a8-e913-507fd486ed71}</Project>
+      <Name>UniRx</Name>
+    </ProjectReference>
+    <ProjectReference Include="Fort23.Core.csproj">
+      <Project>{445e7699-1039-047b-4806-470bcc01c6b3}</Project>
+      <Name>Fort23.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="NewAssembly.csproj">
+      <Project>{ef8f7edb-e142-c812-09c9-1efd42e75660}</Project>
+      <Name>NewAssembly</Name>
+    </ProjectReference>
+    <ProjectReference Include="Unity.AI.Navigation.csproj">
+      <Project>{6ec9c639-b54b-a18e-c822-0caa72f912e9}</Project>
+      <Name>Unity.AI.Navigation</Name>
+    </ProjectReference>
+    <ProjectReference Include="Kybernetik.Animancer.Editor.csproj">
+      <Project>{7ff57b24-3cdc-f1f3-965d-b7f88f25eba7}</Project>
+      <Name>Kybernetik.Animancer.Editor</Name>
+    </ProjectReference>
+    <ProjectReference Include="GPUECSAnimationBakerEngine.csproj">
+      <Project>{4e427888-6063-b2e4-7133-1f5331d2804d}</Project>
+      <Name>GPUECSAnimationBakerEngine</Name>
+    </ProjectReference>
+    <ProjectReference Include="Fort23.GameLogic.csproj">
+      <Project>{aa8b3008-7748-fe09-d0e8-e77da33c4943}</Project>
+      <Name>Fort23.GameLogic</Name>
+    </ProjectReference>
+    <ProjectReference Include="CodeStage.AFPSCounter.Editor.csproj">
+      <Project>{b2cf76b8-ee1d-c452-8c93-3c88f47c785b}</Project>
+      <Name>CodeStage.AFPSCounter.Editor</Name>
+    </ProjectReference>
+    <ProjectReference Include="Unity.AI.Navigation.Samples.csproj">
+      <Project>{c2199000-def0-facf-890c-7b0559fa37a3}</Project>
+      <Name>Unity.AI.Navigation.Samples</Name>
+    </ProjectReference>
+    <ProjectReference Include="Unity.AI.Navigation.Editor.ConversionSystem.csproj">
+      <Project>{f6528f8b-dbb4-84ed-ee55-12bcabff9780}</Project>
+      <Name>Unity.AI.Navigation.Editor.ConversionSystem</Name>
+    </ProjectReference>
+    <ProjectReference Include="CoreEditor.csproj">
+      <Project>{f10734e3-11fb-7644-3560-693b65970297}</Project>
+      <Name>CoreEditor</Name>
+    </ProjectReference>
     <ProjectReference Include="Fort23.Mono.csproj">
       <Project>{8922979a-7100-3ac2-8b6d-b37f70a05dc5}</Project>
       <Name>Fort23.Mono</Name>
@@ -1192,10 +1292,6 @@
       <Project>{37f1f42e-8ca9-390b-4277-426936703ada}</Project>
       <Name>Fort23.GameData</Name>
     </ProjectReference>
-    <ProjectReference Include="CodeStage.AFPSCounter.Runtime.csproj">
-      <Project>{e69dd175-3705-64b7-6de3-d7bad627f6f5}</Project>
-      <Name>CodeStage.AFPSCounter.Runtime</Name>
-    </ProjectReference>
     <ProjectReference Include="Kybernetik.Animancer.csproj">
       <Project>{efb3aa66-4279-eaf4-280d-79e6d8ad1f40}</Project>
       <Name>Kybernetik.Animancer</Name>
@@ -1208,10 +1304,6 @@
       <Project>{82e3b869-9260-65b9-ff66-1cff0654fc3d}</Project>
       <Name>EnhancedHierarchyEditor</Name>
     </ProjectReference>
-    <ProjectReference Include="DownloadSystem.csproj">
-      <Project>{bcbcbf0b-c587-3257-d934-4f5bafbff086}</Project>
-      <Name>DownloadSystem</Name>
-    </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

+ 8 - 0
Assets/Art/ArtHero/BakedAssets_Guaiwu01.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: WX4XtXykVXmkqdVKlQj7ZOQKWKGRvi+ktnhD2cgLpL/k5/1tX4LQohE=
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

文件差異過大導致無法顯示
+ 50 - 0
Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_AnimationMatricesTexture_Snakelet.asset


+ 8 - 0
Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_AnimationMatricesTexture_Snakelet.asset.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: DX9KsCyvAn+kYEeApSYYT6G+80XFBT2Kh8wH+1NzoYSc8oT57PCKSjs=
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2800000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 218 - 0
Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_GpuEcsAnimator.prefab

@@ -0,0 +1,218 @@
+%YAML 1.1
+%TAG !u! tag:yousandi.cn,2023:
+--- !u!1 &4573799512793257522
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 7
+  m_Component:
+  - component: {fileID: 7914018815068294423}
+  - component: {fileID: 2587504306462188448}
+  m_Layer: 0
+  m_HasEditorInfo: 1
+  m_Name: Guaiwu01_GpuEcsAnimator
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &7914018815068294423
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4573799512793257522}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 8476578454633010118}
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &2587504306462188448
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4573799512793257522}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6dbd5b1412c14f19ba40d2188c5cd8c1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  totalNbrOfFrames: 222
+  nbrOfAttachmentAnchors: 0
+  animations:
+  - startFrameIndex: 0
+    nbrOfFramesPerSample: 61
+    nbrOfInBetweenSamples: 1
+    blendTimeCorrection: 1
+    startEventOccurenceId: 0
+    nbrOfEventOccurenceIds: 0
+    loop: 1
+    animationID: idle
+    stateName: idle
+  - startFrameIndex: 61
+    nbrOfFramesPerSample: 26
+    nbrOfInBetweenSamples: 1
+    blendTimeCorrection: 1
+    startEventOccurenceId: 0
+    nbrOfEventOccurenceIds: 0
+    loop: 0
+    animationID: BiteAttack
+    stateName: Bite Attack
+  - startFrameIndex: 87
+    nbrOfFramesPerSample: 31
+    nbrOfInBetweenSamples: 1
+    blendTimeCorrection: 1
+    startEventOccurenceId: 0
+    nbrOfEventOccurenceIds: 0
+    loop: 0
+    animationID: CastSpell
+    stateName: Cast Spell
+  - startFrameIndex: 118
+    nbrOfFramesPerSample: 41
+    nbrOfInBetweenSamples: 1
+    blendTimeCorrection: 1
+    startEventOccurenceId: 0
+    nbrOfEventOccurenceIds: 0
+    loop: 0
+    animationID: Die
+    stateName: Die
+  - startFrameIndex: 159
+    nbrOfFramesPerSample: 26
+    nbrOfInBetweenSamples: 1
+    blendTimeCorrection: 1
+    startEventOccurenceId: 0
+    nbrOfEventOccurenceIds: 0
+    loop: 0
+    animationID: Spawn
+    stateName: Spawn
+  - startFrameIndex: 185
+    nbrOfFramesPerSample: 11
+    nbrOfInBetweenSamples: 1
+    blendTimeCorrection: 1
+    startEventOccurenceId: 0
+    nbrOfEventOccurenceIds: 0
+    loop: 1
+    animationID: Underground
+    stateName: Underground
+  - startFrameIndex: 196
+    nbrOfFramesPerSample: 26
+    nbrOfInBetweenSamples: 1
+    blendTimeCorrection: 1
+    startEventOccurenceId: 0
+    nbrOfEventOccurenceIds: 0
+    loop: 1
+    animationID: run
+    stateName: run
+  animationEventOccurences: []
+  transformUsageFlags: 2
+  attachmentAnchorData: {fileID: 0}
+--- !u!1 &5949725885898124089
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 7
+  m_Component:
+  - component: {fileID: 8476578454633010118}
+  - component: {fileID: 5516422998436364662}
+  - component: {fileID: 540543588441176530}
+  - component: {fileID: 2359220822075819078}
+  m_Layer: 0
+  m_HasEditorInfo: 1
+  m_Name: Snakelet
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &8476578454633010118
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5949725885898124089}
+  serializedVersion: 2
+  m_LocalRotation: {x: -0.7071068, y: 0, z: -0, w: 0.7071068}
+  m_LocalPosition: {x: 3.7880957e-10, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 7914018815068294423}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &5516422998436364662
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5949725885898124089}
+  m_Mesh: {fileID: 4300000, guid: 71d66b7ab83b4be4296f04077623d138, type: 2}
+--- !u!23 &540543588441176530
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5949725885898124089}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_StaticShadowCaster: 0
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RayTracingMode: 2
+  m_RayTraceProcedural: 0
+  m_virtualGeometry: 0
+  m_virtualGeometryShadow: 0
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 2100000, guid: 66343b110f2173a40978afdb851ace4e, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_ReceiveGI: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_AdditionalVertexStreams: {fileID: 0}
+--- !u!114 &2359220822075819078
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5949725885898124089}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: b927b9dfd6f248378c3364a809fda80f, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  animator: {fileID: 2587504306462188448}
+  transformUsageFlags: 1

+ 7 - 0
Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_GpuEcsAnimator.prefab.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: Wnge5i6tUCmAKNcV9bLHiE7BtLHEZ8HYrLU99/x6HzcoPqSSAvfs4Nk=
+PrefabImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 148 - 0
Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_Material_Snakelet.mat

@@ -0,0 +1,148 @@
+%YAML 1.1
+%TAG !u! tag:yousandi.cn,2023:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 8
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Guaiwu01_Material_Snakelet
+  m_Shader: {fileID: -6465566751694194690, guid: de8b10515e8c7b6419b7a2e25ccbf055, type: 3}
+  m_Parent: {fileID: 0}
+  m_ModifiedSerializedProperties: 0
+  m_ValidKeywords: []
+  m_InvalidKeywords: []
+  m_LightmapFlags: 2
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_LockedProperties: 
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _AnimatedBoneMatrices:
+        m_Texture: {fileID: 2800000, guid: 25e562a4fef855446bd8af0f1c29e74a, type: 2}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _Base:
+        m_Texture: {fileID: 2800000, guid: 5b35f2382631bdf47ab344060737b580, type: 3}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BaseMap:
+        m_Texture: {fileID: 2800000, guid: 8016c10e702af7d47ad02b98dee125c1, type: 3}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 2800000, guid: a56254110c469a549acaf09f64f72258, type: 3}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 2800000, guid: 8016c10e702af7d47ad02b98dee125c1, type: 3}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _Normal:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _SpecGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_Lightmaps:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_LightmapsInd:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - unity_ShadowMasks:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Ints: []
+    m_Floats:
+    - _AlphaClip: 0
+    - _AlphaToMask: 0
+    - _Blend: 0
+    - _BlendModePreserveSpecular: 1
+    - _BumpScale: 1
+    - _ClearCoatMask: 0
+    - _ClearCoatSmoothness: 0
+    - _Cull: 2
+    - _Cutoff: 0.5
+    - _DetailAlbedoMapScale: 1
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _DstBlendAlpha: 0
+    - _EnableAnimation: 1
+    - _EnvironmentReflections: 1
+    - _GlossMapScale: 1
+    - _Glossiness: 0
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _QueueControl: 0
+    - _QueueOffset: 0
+    - _ReceiveShadows: 1
+    - _Smoothness: 0
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 0
+    - _SrcBlend: 1
+    - _SrcBlendAlpha: 1
+    - _Surface: 0
+    - _UVSec: 0
+    - _WorkflowMode: 1
+    - _ZWrite: 1
+    m_Colors:
+    - _BaseColor: {r: 1, g: 1, b: 1, a: 1}
+    - _Color: {r: 1, g: 1, b: 1, a: 1}
+    - _EmissionColor: {r: 1, g: 0, b: 0, a: 1}
+    - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
+  m_BuildTextureStacks: []
+--- !u!114 &4753996462854978707
+MonoBehaviour:
+  m_ObjectHideFlags: 11
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  version: 7

+ 8 - 0
Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_Material_Snakelet.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: CXwcsSn/UnqH9aXilS+aTtYtgHToM4J/PntElikKghNSiphEy0aws+4=
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

文件差異過大導致無法顯示
+ 358 - 0
Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_Mesh_Snakelet.mesh


+ 8 - 0
Assets/Art/ArtHero/BakedAssets_Guaiwu01/Guaiwu01_Mesh_Snakelet.mesh.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: CHtLsyz/VCpareuEfuQq7jGPcpjDkRjbsfMT3cGcLO2cQv0B3fTvTyU=
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 4300000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 150 - 1
Assets/Art/ArtHero/Guaiwu01.prefab

@@ -1277,6 +1277,7 @@ GameObject:
   - component: {fileID: 3012581834444235609}
   - component: {fileID: 3937025198469130874}
   - component: {fileID: -2389684715378374559}
+  - component: {fileID: -8725904427751630163}
   m_Layer: 0
   m_HasEditorInfo: 1
   m_Name: Guaiwu01
@@ -1328,7 +1329,7 @@ Animator:
   m_GameObject: {fileID: 7636340872322017040}
   m_Enabled: 1
   m_Avatar: {fileID: 9000000, guid: 0b080fb945711ae47abb40495a599b9b, type: 3}
-  m_Controller: {fileID: 0}
+  m_Controller: {fileID: 9100000, guid: 965d15d735575274896b1aca47c37250, type: 2}
   m_CullingMode: 1
   m_UpdateMode: 0
   m_ApplyRootMotion: 0
@@ -1456,6 +1457,154 @@ BoxCollider:
   serializedVersion: 3
   m_Size: {x: 1, y: 1.5, z: 1}
   m_Center: {x: 0, y: 0.7, z: 0}
+--- !u!114 &-8725904427751630163
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 7636340872322017040}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e861cd728fd49b69e30e17bd76642da, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  bakerData:
+    animations:
+    - animationID: idle
+      animatorStateName: idle
+      animationType: 0
+      singleClipData:
+        animationClip: {fileID: 7400000, guid: 211c387469166a94a8231490d3329181, type: 3}
+      dualClipBlendData:
+        blendParameterName: 
+        clip1:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        clip2:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        nbrOfInBetweenSamples: 0
+      loop: 1
+      additionalAnimatorParameterValues: []
+      additionalAnimatorStatesPerLayer: []
+    - animationID: BiteAttack
+      animatorStateName: Bite Attack
+      animationType: 0
+      singleClipData:
+        animationClip: {fileID: 7400000, guid: 6914c74b218b2044ea2c463ae289d898, type: 3}
+      dualClipBlendData:
+        blendParameterName: 
+        clip1:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        clip2:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        nbrOfInBetweenSamples: 0
+      loop: 0
+      additionalAnimatorParameterValues: []
+      additionalAnimatorStatesPerLayer: []
+    - animationID: CastSpell
+      animatorStateName: Cast Spell
+      animationType: 0
+      singleClipData:
+        animationClip: {fileID: 7400000, guid: e40f0b936e6f87b49adffb816a83f69c, type: 3}
+      dualClipBlendData:
+        blendParameterName: 
+        clip1:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        clip2:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        nbrOfInBetweenSamples: 0
+      loop: 0
+      additionalAnimatorParameterValues: []
+      additionalAnimatorStatesPerLayer: []
+    - animationID: Die
+      animatorStateName: Die
+      animationType: 0
+      singleClipData:
+        animationClip: {fileID: 7400000, guid: c1694ad78d2b8ca4fa7d27c700415665, type: 3}
+      dualClipBlendData:
+        blendParameterName: 
+        clip1:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        clip2:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        nbrOfInBetweenSamples: 0
+      loop: 0
+      additionalAnimatorParameterValues: []
+      additionalAnimatorStatesPerLayer: []
+    - animationID: Spawn
+      animatorStateName: Spawn
+      animationType: 0
+      singleClipData:
+        animationClip: {fileID: 7400000, guid: 3851dd3b76e86f84ca990b222a770ff0, type: 3}
+      dualClipBlendData:
+        blendParameterName: 
+        clip1:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        clip2:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        nbrOfInBetweenSamples: 0
+      loop: 0
+      additionalAnimatorParameterValues: []
+      additionalAnimatorStatesPerLayer: []
+    - animationID: Underground
+      animatorStateName: Underground
+      animationType: 0
+      singleClipData:
+        animationClip: {fileID: 7400000, guid: 3c755deea655c7d4190f226792da5189, type: 3}
+      dualClipBlendData:
+        blendParameterName: 
+        clip1:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        clip2:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        nbrOfInBetweenSamples: 0
+      loop: 1
+      additionalAnimatorParameterValues: []
+      additionalAnimatorStatesPerLayer: []
+    - animationID: run
+      animatorStateName: run
+      animationType: 0
+      singleClipData:
+        animationClip: {fileID: 7400000, guid: e9e97ff4e8a989e47af733dafd080787, type: 3}
+      dualClipBlendData:
+        blendParameterName: 
+        clip1:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        clip2:
+          parameterValue: 0
+          animationClip: {fileID: 0}
+        nbrOfInBetweenSamples: 0
+      loop: 1
+      additionalAnimatorParameterValues: []
+      additionalAnimatorStatesPerLayer: []
+    generateAnimationIdsEnum: 0
+    animationIdsEnumName: 
+    usePredefinedAnimationEventIds: 0
+    predefinedAnimationEventIds: []
+    generateAnimationEventIdsEnum: 0
+    animationEventIdsEnumName: 
+    attachmentAnchors: []
+    generateAttachmentAnchorIdsEnum: 0
+    attachmentAnchorIdsEnumName: 
+    boneUsage:
+      numberOfBonesPerVertex: 6
+      boneUsagesPerLoD: []
+    transformUsageFlagsParent: 2
+    transformUsageFlagsChildren: 1
+  gpuEcsAnimator: {fileID: 4573799512793257522, guid: e21c403bf42561e47844837b065cd211, type: 3}
 --- !u!1 &7750704757169647667
 GameObject:
   m_ObjectHideFlags: 0

+ 203 - 0
Assets/Art/ArtHero/Guaiwu01_gpu.prefab

@@ -0,0 +1,203 @@
+%YAML 1.1
+%TAG !u! tag:yousandi.cn,2023:
+--- !u!1 &1486648135052072193
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 7
+  m_Component:
+  - component: {fileID: 2254773846348706746}
+  - component: {fileID: 7626962916459775227}
+  - component: {fileID: 4408512263679554551}
+  - component: {fileID: 4770066491419026642}
+  m_Layer: 0
+  m_HasEditorInfo: 1
+  m_Name: Guaiwu01_gpu
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &2254773846348706746
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1486648135052072193}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -1.93, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 8460209264768730837}
+  - {fileID: 1187023392652981393}
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!54 &7626962916459775227
+Rigidbody:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1486648135052072193}
+  serializedVersion: 4
+  m_Mass: 1
+  m_Drag: 0
+  m_AngularDrag: 0.05
+  m_CenterOfMass: {x: 0, y: 0, z: 0}
+  m_InertiaTensor: {x: 1, y: 1, z: 1}
+  m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ImplicitCom: 1
+  m_ImplicitTensor: 1
+  m_UseGravity: 1
+  m_IsKinematic: 1
+  m_Interpolate: 0
+  m_Constraints: 0
+  m_CollisionDetection: 0
+--- !u!195 &4408512263679554551
+NavMeshAgent:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1486648135052072193}
+  m_Enabled: 1
+  m_AgentTypeID: 0
+  m_Radius: 0.21
+  m_Speed: 3.5
+  m_Acceleration: 8
+  avoidancePriority: 50
+  m_AngularSpeed: 720
+  m_StoppingDistance: 0.5
+  m_AutoTraverseOffMeshLink: 1
+  m_AutoBraking: 0
+  m_AutoRepath: 1
+  m_Height: 0.8
+  m_BaseOffset: 0
+  m_WalkableMask: 4294967295
+  m_ObstacleAvoidanceType: 4
+--- !u!65 &4770066491419026642
+BoxCollider:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1486648135052072193}
+  m_Material: {fileID: 0}
+  m_IncludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_ExcludeLayers:
+    serializedVersion: 2
+    m_Bits: 0
+  m_LayerOverridePriority: 0
+  m_IsTrigger: 0
+  m_ProvidesContacts: 0
+  m_Enabled: 1
+  serializedVersion: 3
+  m_Size: {x: 1, y: 1.5, z: 1}
+  m_Center: {x: 0, y: 0.7, z: 0}
+--- !u!1 &6192587680073998837
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 7
+  m_Component:
+  - component: {fileID: 1187023392652981393}
+  m_Layer: 0
+  m_HasEditorInfo: 1
+  m_Name: hp
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1187023392652981393
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6192587680073998837}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0.887, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 2254773846348706746}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1001 &1782455331161705410
+PrefabInstance:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    serializedVersion: 3
+    m_TransformParent: {fileID: 2254773846348706746}
+    m_Modifications:
+    - target: {fileID: 4573799512793257522, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_Name
+      value: Guaiwu01_GpuEcsAnimator
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+      propertyPath: m_LocalEulerAnglesHint.z
+      value: 0
+      objectReference: {fileID: 0}
+    m_RemovedComponents: []
+    m_RemovedGameObjects: []
+    m_AddedGameObjects: []
+    m_AddedComponents: []
+  m_SourcePrefab: {fileID: 100100000, guid: e21c403bf42561e47844837b065cd211, type: 3}
+--- !u!4 &8460209264768730837 stripped
+Transform:
+  m_CorrespondingSourceObject: {fileID: 7914018815068294423, guid: e21c403bf42561e47844837b065cd211, type: 3}
+  m_PrefabInstance: {fileID: 1782455331161705410}
+  m_PrefabAsset: {fileID: 0}

+ 7 - 0
Assets/Art/ArtHero/Guaiwu01_gpu.prefab.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: Di5LvCj5B3t6RKd9eLEYXzioVXHRcz2fhe/vUl15Ngjy08SRuyhS9E8=
+PrefabImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 246 - 0
Assets/Art/ArtHero/New Animator Controller.controller

@@ -0,0 +1,246 @@
+%YAML 1.1
+%TAG !u! tag:yousandi.cn,2023:
+--- !u!1102 &-7552075266120333533
+AnimatorState:
+  serializedVersion: 6
+  m_ObjectHideFlags: 1
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Die
+  m_Speed: 1
+  m_CycleOffset: 0
+  m_Transitions: []
+  m_StateMachineBehaviours: []
+  m_Position: {x: 50, y: 50, z: 0}
+  m_IKOnFeet: 0
+  m_WriteDefaultValues: 1
+  m_Mirror: 0
+  m_SpeedParameterActive: 0
+  m_MirrorParameterActive: 0
+  m_CycleOffsetParameterActive: 0
+  m_TimeParameterActive: 0
+  m_Motion: {fileID: 7400000, guid: c1694ad78d2b8ca4fa7d27c700415665, type: 3}
+  m_Tag: 
+  m_SpeedParameter: 
+  m_MirrorParameter: 
+  m_CycleOffsetParameter: 
+  m_TimeParameter: 
+--- !u!1102 &-5010781657122618946
+AnimatorState:
+  serializedVersion: 6
+  m_ObjectHideFlags: 1
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Bite Attack
+  m_Speed: 1
+  m_CycleOffset: 0
+  m_Transitions: []
+  m_StateMachineBehaviours: []
+  m_Position: {x: 50, y: 50, z: 0}
+  m_IKOnFeet: 0
+  m_WriteDefaultValues: 1
+  m_Mirror: 0
+  m_SpeedParameterActive: 0
+  m_MirrorParameterActive: 0
+  m_CycleOffsetParameterActive: 0
+  m_TimeParameterActive: 0
+  m_Motion: {fileID: 7400000, guid: 6914c74b218b2044ea2c463ae289d898, type: 3}
+  m_Tag: 
+  m_SpeedParameter: 
+  m_MirrorParameter: 
+  m_CycleOffsetParameter: 
+  m_TimeParameter: 
+--- !u!1102 &-4137464293386390658
+AnimatorState:
+  serializedVersion: 6
+  m_ObjectHideFlags: 1
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Spawn
+  m_Speed: 1
+  m_CycleOffset: 0
+  m_Transitions: []
+  m_StateMachineBehaviours: []
+  m_Position: {x: 50, y: 50, z: 0}
+  m_IKOnFeet: 0
+  m_WriteDefaultValues: 1
+  m_Mirror: 0
+  m_SpeedParameterActive: 0
+  m_MirrorParameterActive: 0
+  m_CycleOffsetParameterActive: 0
+  m_TimeParameterActive: 0
+  m_Motion: {fileID: 7400000, guid: 3851dd3b76e86f84ca990b222a770ff0, type: 3}
+  m_Tag: 
+  m_SpeedParameter: 
+  m_MirrorParameter: 
+  m_CycleOffsetParameter: 
+  m_TimeParameter: 
+--- !u!1102 &-135049555308940568
+AnimatorState:
+  serializedVersion: 6
+  m_ObjectHideFlags: 1
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Underground
+  m_Speed: 1
+  m_CycleOffset: 0
+  m_Transitions: []
+  m_StateMachineBehaviours: []
+  m_Position: {x: 50, y: 50, z: 0}
+  m_IKOnFeet: 0
+  m_WriteDefaultValues: 1
+  m_Mirror: 0
+  m_SpeedParameterActive: 0
+  m_MirrorParameterActive: 0
+  m_CycleOffsetParameterActive: 0
+  m_TimeParameterActive: 0
+  m_Motion: {fileID: 7400000, guid: 3c755deea655c7d4190f226792da5189, type: 3}
+  m_Tag: 
+  m_SpeedParameter: 
+  m_MirrorParameter: 
+  m_CycleOffsetParameter: 
+  m_TimeParameter: 
+--- !u!91 &9100000
+AnimatorController:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: New Animator Controller
+  serializedVersion: 5
+  m_AnimatorParameters: []
+  m_AnimatorLayers:
+  - serializedVersion: 5
+    m_Name: Base Layer
+    m_StateMachine: {fileID: 7813710424225025242}
+    m_Mask: {fileID: 0}
+    m_Motions: []
+    m_Behaviours: []
+    m_BlendingMode: 0
+    m_SyncedLayerIndex: -1
+    m_DefaultWeight: 0
+    m_IKPass: 0
+    m_SyncedLayerAffectsTiming: 0
+    m_Controller: {fileID: 9100000}
+--- !u!1102 &4998145492315884334
+AnimatorState:
+  serializedVersion: 6
+  m_ObjectHideFlags: 1
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: run
+  m_Speed: 1
+  m_CycleOffset: 0
+  m_Transitions: []
+  m_StateMachineBehaviours: []
+  m_Position: {x: 50, y: 50, z: 0}
+  m_IKOnFeet: 0
+  m_WriteDefaultValues: 1
+  m_Mirror: 0
+  m_SpeedParameterActive: 0
+  m_MirrorParameterActive: 0
+  m_CycleOffsetParameterActive: 0
+  m_TimeParameterActive: 0
+  m_Motion: {fileID: 7400000, guid: e9e97ff4e8a989e47af733dafd080787, type: 3}
+  m_Tag: 
+  m_SpeedParameter: 
+  m_MirrorParameter: 
+  m_CycleOffsetParameter: 
+  m_TimeParameter: 
+--- !u!1102 &5437703490706116676
+AnimatorState:
+  serializedVersion: 6
+  m_ObjectHideFlags: 1
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Cast Spell
+  m_Speed: 1
+  m_CycleOffset: 0
+  m_Transitions: []
+  m_StateMachineBehaviours: []
+  m_Position: {x: 50, y: 50, z: 0}
+  m_IKOnFeet: 0
+  m_WriteDefaultValues: 1
+  m_Mirror: 0
+  m_SpeedParameterActive: 0
+  m_MirrorParameterActive: 0
+  m_CycleOffsetParameterActive: 0
+  m_TimeParameterActive: 0
+  m_Motion: {fileID: 7400000, guid: e40f0b936e6f87b49adffb816a83f69c, type: 3}
+  m_Tag: 
+  m_SpeedParameter: 
+  m_MirrorParameter: 
+  m_CycleOffsetParameter: 
+  m_TimeParameter: 
+--- !u!1102 &5811431598696386155
+AnimatorState:
+  serializedVersion: 6
+  m_ObjectHideFlags: 1
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: idle
+  m_Speed: 1
+  m_CycleOffset: 0
+  m_Transitions: []
+  m_StateMachineBehaviours: []
+  m_Position: {x: 50, y: 50, z: 0}
+  m_IKOnFeet: 0
+  m_WriteDefaultValues: 1
+  m_Mirror: 0
+  m_SpeedParameterActive: 0
+  m_MirrorParameterActive: 0
+  m_CycleOffsetParameterActive: 0
+  m_TimeParameterActive: 0
+  m_Motion: {fileID: 7400000, guid: 211c387469166a94a8231490d3329181, type: 3}
+  m_Tag: 
+  m_SpeedParameter: 
+  m_MirrorParameter: 
+  m_CycleOffsetParameter: 
+  m_TimeParameter: 
+--- !u!1107 &7813710424225025242
+AnimatorStateMachine:
+  serializedVersion: 6
+  m_ObjectHideFlags: 1
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Base Layer
+  m_ChildStates:
+  - serializedVersion: 1
+    m_State: {fileID: 5811431598696386155}
+    m_Position: {x: 186.07928, y: 220.7821, z: 0}
+  - serializedVersion: 1
+    m_State: {fileID: -5010781657122618946}
+    m_Position: {x: 315.19397, y: 125.56003, z: 0}
+  - serializedVersion: 1
+    m_State: {fileID: 5437703490706116676}
+    m_Position: {x: 319.22882, y: 49.70514, z: 0}
+  - serializedVersion: 1
+    m_State: {fileID: -7552075266120333533}
+    m_Position: {x: 320.84274, y: 3.7080383, z: 0}
+  - serializedVersion: 1
+    m_State: {fileID: -4137464293386390658}
+    m_Position: {x: 430, y: 200, z: 0}
+  - serializedVersion: 1
+    m_State: {fileID: -135049555308940568}
+    m_Position: {x: 430.40036, y: 285.14954, z: 0}
+  - serializedVersion: 1
+    m_State: {fileID: 4998145492315884334}
+    m_Position: {x: 289.8932, y: 340.21313, z: 0}
+  m_ChildStateMachines: []
+  m_AnyStateTransitions: []
+  m_EntryTransitions: []
+  m_StateMachineTransitions: {}
+  m_StateMachineBehaviours: []
+  m_AnyStatePosition: {x: 50, y: 20, z: 0}
+  m_EntryPosition: {x: 50, y: 120, z: 0}
+  m_ExitPosition: {x: 800, y: 120, z: 0}
+  m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
+  m_DefaultState: {fileID: 5811431598696386155}

+ 8 - 0
Assets/Art/ArtHero/New Animator Controller.controller.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: Bnwa4SuoB3x5bgcctfGr427vHtTYiTxwH5wggOOzhxz2ZIGgmY9+RRE=
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 9100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/GPUECSAnimationBaker.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f4c3389b5ff4d6e4abe5366fd711368b
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/GPUECSAnimationBaker/Engine.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b0b9df4a408a23e4d8c0a43fb8defcf1
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 124891a7ea58427880af54e98f143795
+timeCreated: 1678872127

+ 37 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshBehaviour.cs

@@ -0,0 +1,37 @@
+using Unity.Entities;
+using Unity.Mathematics;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    public class GpuEcsAnimatedMeshBehaviour : MonoBehaviour
+    {
+        public GpuEcsAnimatorBehaviour animator;
+        public TransformUsageFlags transformUsageFlags = TransformUsageFlags.Renderable;
+    }
+    
+    public class GpuEcsAnimatedMeshBaker : Baker<GpuEcsAnimatedMeshBehaviour>
+    {
+        public override void Bake(GpuEcsAnimatedMeshBehaviour authoring)
+        {
+            Entity entity = GetEntity(authoring.transformUsageFlags);
+            AddComponent(entity, new GpuEcsAnimatedMeshComponent()
+            {
+                animatorEntity = GetEntity(authoring.animator.gameObject,
+                    authoring.animator.transformUsageFlags)
+            });
+            AddComponent(entity, new GpuEcsMaterialAnimationState()
+            {
+                Value = new float4x4(
+                    1f, 0, 0, 0, 
+                    0, 0, 0, 0, 
+                    0, 0, 0, 0,
+                    0, 0, 0, 0)
+            });
+            AddComponent(entity, new GpuEcsMaterialEnableAnimation()
+            {
+                Value = 1
+            });
+        }
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshBehaviour.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: b927b9dfd6f248378c3364a809fda80f
+timeCreated: 1678872326

+ 24 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshComponents.cs

@@ -0,0 +1,24 @@
+using Unity.Entities;
+using Unity.Mathematics;
+using Unity.Rendering;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    public struct GpuEcsAnimatedMeshComponent : IComponentData
+    {
+        public Entity animatorEntity;
+    }
+
+    [MaterialProperty("_AnimationState")]
+    public struct GpuEcsMaterialAnimationState : IComponentData
+    {
+        public float4x4 Value;
+    }
+
+    [MaterialProperty("_EnableAnimation")]
+    public struct GpuEcsMaterialEnableAnimation : IComponentData
+    {
+        public float Value;
+    }
+    
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshComponents.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: e6415d1f6b424b518f1027adf467f308
+timeCreated: 1678872217

+ 40 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshSystem.cs

@@ -0,0 +1,40 @@
+using Unity.Burst;
+using Unity.Collections;
+using Unity.Entities;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    public partial struct GpuEcsAnimatedMeshSystem : ISystem
+    {
+        private ComponentLookup<GpuEcsAnimatorShaderDataComponent> gpuEcsAnimatorShaderDataLookup;
+            
+        [BurstCompile]
+        public void OnCreate(ref SystemState state)
+        {
+            gpuEcsAnimatorShaderDataLookup = state.GetComponentLookup<GpuEcsAnimatorShaderDataComponent>(isReadOnly: true);
+        }
+        
+        [BurstCompile]
+        public void OnUpdate(ref SystemState state)
+        {
+            gpuEcsAnimatorShaderDataLookup.Update(ref state);
+            state.Dependency = new GpuEcsAnimatedMeshJob()
+            {
+                gpuEcsAnimatorShaderDataLookup = gpuEcsAnimatorShaderDataLookup
+            }.ScheduleParallel(state.Dependency);
+        }
+        
+        [BurstCompile]
+        private partial struct GpuEcsAnimatedMeshJob : IJobEntity
+        {
+            [ReadOnly] public ComponentLookup<GpuEcsAnimatorShaderDataComponent> gpuEcsAnimatorShaderDataLookup;
+
+            public void Execute(ref GpuEcsMaterialAnimationState gpuEcsMaterialAnimationState,
+                in GpuEcsAnimatedMeshComponent gpuEcsAnimatedMesh)
+            {
+                GpuEcsAnimatorShaderDataComponent gpuEcsAnimatorShaderData = gpuEcsAnimatorShaderDataLookup[gpuEcsAnimatedMesh.animatorEntity];
+                gpuEcsMaterialAnimationState.Value = gpuEcsAnimatorShaderData.shaderData;
+            }
+        }        
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatedMeshSystem.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 09f4119292fd4cba8f97647ead766325
+timeCreated: 1678872951

+ 18 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimationData.cs

@@ -0,0 +1,18 @@
+using System;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    [Serializable]
+    public class GpuEcsAnimationData
+    {
+        public int startFrameIndex;
+        public int nbrOfFramesPerSample;
+        public int nbrOfInBetweenSamples;
+        public float blendTimeCorrection;
+        public int startEventOccurenceId;
+        public int nbrOfEventOccurenceIds;
+        public bool loop;
+        public string animationID;
+        public string stateName;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimationData.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: cf4ba1c380704a3aa0f7345cc23f2921
+timeCreated: 1678894498

+ 41 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorAspect.cs

@@ -0,0 +1,41 @@
+using Unity.Entities;
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    public readonly partial struct GpuEcsAnimatorAspect : IAspect
+    {
+        private readonly RefRW<GpuEcsAnimatorControlComponent> control;
+        private readonly RefRW<GpuEcsAnimatorControlStateComponent> controlState;
+
+        public void RunAnimation(int animationID,
+            float blendFactor = 0f, float speedFactor = 1f, float startNormalizedTime = 0f, float transitionSpeed = 0f)
+        {
+            control.ValueRW = new GpuEcsAnimatorControlComponent()
+            {
+                animatorInfo = new AnimatorInfo()
+                {
+                    animationID = animationID,
+                    blendFactor = blendFactor,
+                    speedFactor = speedFactor
+                },
+                startNormalizedTime = startNormalizedTime,
+                transitionSpeed = transitionSpeed
+            };
+            StartAnimation();
+        }
+
+        public void StartAnimation()
+        {
+            controlState.ValueRW = new GpuEcsAnimatorControlStateComponent() {
+                state = GpuEcsAnimatorControlStates.Start
+            };
+        }
+        
+        public void StopAnimation()
+        {
+            controlState.ValueRW = new GpuEcsAnimatorControlStateComponent() {
+                state = GpuEcsAnimatorControlStates.Stop
+            };
+        }
+        
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorAspect.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: a76237f7b8ca482695bb8c544895fc00
+timeCreated: 1679903062

+ 123 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorBehaviour.cs

@@ -0,0 +1,123 @@
+using System;
+using GpuEcsAnimationBaker.Engine.Data;
+using Unity.Collections;
+using Unity.Entities;
+using Unity.Mathematics;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    public class GpuEcsAnimatorBehaviour : MonoBehaviour
+    {
+        public int totalNbrOfFrames;
+        public int nbrOfAttachmentAnchors;
+        public GpuEcsAnimationData[] animations;
+        public GpuEcsAnimationEventOccurence[] animationEventOccurences;
+        public TransformUsageFlags transformUsageFlags = TransformUsageFlags.Dynamic;
+        public GpuEcsAttachmentAnchorData attachmentAnchorData;
+        // public AnimationData[] BackAnimationDatas;
+    }
+
+    [Serializable]
+    public struct GpuEcsAnimationEventOccurence
+    {
+        public float eventNormalizedTime;
+        public int eventId;
+    }
+
+    public class GpuEcsAnimatorBaker : Baker<GpuEcsAnimatorBehaviour>
+    {
+        public override void Bake(GpuEcsAnimatorBehaviour authoring)
+        {
+            Entity entity = GetEntity(authoring.transformUsageFlags);
+
+            AddComponent(entity, new GpuEcsAnimationDataComponent()
+            {
+                nbrOfAttachmentAnchors = authoring.nbrOfAttachmentAnchors,
+                totalNbrOfFrames = authoring.totalNbrOfFrames
+            });
+            
+            DynamicBuffer<GpuEcsAnimationDataBufferElement> gpuEcsAnimationDataBuffer = AddBuffer<GpuEcsAnimationDataBufferElement>(entity);
+            for (int animationIndex = 0; animationIndex < authoring.animations.Length; animationIndex++)
+            {
+                GpuEcsAnimationData gpuEcsAnimationData = authoring.animations[animationIndex];
+                gpuEcsAnimationDataBuffer.Add(new GpuEcsAnimationDataBufferElement()
+                {
+                    startFrameIndex = gpuEcsAnimationData.startFrameIndex,
+                    nbrOfFramesPerSample = gpuEcsAnimationData.nbrOfFramesPerSample,
+                    nbrOfInBetweenSamples = gpuEcsAnimationData.nbrOfInBetweenSamples,
+                    blendTimeCorrection = gpuEcsAnimationData.blendTimeCorrection,
+                    startEventOccurenceId = gpuEcsAnimationData.startEventOccurenceId,
+                    nbrOfEventOccurenceIds = gpuEcsAnimationData.nbrOfEventOccurenceIds,
+                    loop = gpuEcsAnimationData.loop
+                });
+            }
+            
+            DynamicBuffer<GpuEcsAnimationEventOccurenceBufferElement> gpuEcsAnimationEventOccurenceBuffer = AddBuffer<GpuEcsAnimationEventOccurenceBufferElement>(entity);
+            for (int animationEventOccurenceId = 0; animationEventOccurenceId < authoring.animationEventOccurences.Length; animationEventOccurenceId++)
+            {
+                GpuEcsAnimationEventOccurence occurence = authoring.animationEventOccurences[animationEventOccurenceId];
+                gpuEcsAnimationEventOccurenceBuffer.Add(new GpuEcsAnimationEventOccurenceBufferElement()
+                {
+                    eventNormalizedTime = occurence.eventNormalizedTime,
+                    eventId = occurence.eventId
+                });
+            }
+            
+            AddComponent(entity, new GpuEcsAnimatorShaderDataComponent()
+            {
+                shaderData = new float4x4(
+                    1f, 0, 0, 0, 
+                    0, 0, 0, 0, 
+                    0, 0, 0, 0,
+                    0, 0, 0, 0)
+            });
+
+            int initialAnimationID = 0;
+            GpuEcsAnimatorInitializerBehaviour initializer = authoring.GetComponent<GpuEcsAnimatorInitializerBehaviour>();
+            if (initializer != null) initialAnimationID = initializer.GetInitialAnimationID();
+
+            AddComponent(entity, new GpuEcsAnimatorInitializedComponent()
+            {
+                initialized = false
+            });
+            
+            AddComponent(entity, new GpuEcsAnimatorControlComponent()
+            {
+                animatorInfo = new AnimatorInfo()
+                {
+                    animationID = initialAnimationID,
+                    blendFactor = 0,
+                    speedFactor = 1
+                },
+                transitionSpeed = 0,
+                startNormalizedTime = 0
+            });
+            AddComponent(entity, new GpuEcsAnimatorControlStateComponent()
+            {
+                state = GpuEcsAnimatorControlStates.Start
+            });
+                
+            AddComponent<GpuEcsAnimatorTransitionInfoComponent>(entity);
+            AddComponent<GpuEcsAnimatorStateComponent>(entity);
+
+            DynamicBuffer<GpuEcsAttachmentAnchorDataBufferElement> anchorDataBuffer = AddBuffer<GpuEcsAttachmentAnchorDataBufferElement>(entity);
+            DynamicBuffer<GpuEcsCurrentAttachmentAnchorBufferElement> currentAnchorTransformBuffer = AddBuffer<GpuEcsCurrentAttachmentAnchorBufferElement>(entity);
+            if (authoring.attachmentAnchorData != null && authoring.nbrOfAttachmentAnchors > 0)
+            {
+                int anchorDataLength = authoring.attachmentAnchorData.anchorTransforms.Length;
+                NativeArray<GpuEcsAttachmentAnchorDataBufferElement> anchors = new NativeArray<GpuEcsAttachmentAnchorDataBufferElement>(anchorDataLength, Allocator.Temp);
+                for (int i = 0; i < anchorDataLength; i++) 
+                    anchors[i] = new GpuEcsAttachmentAnchorDataBufferElement() { anchorTransform = authoring.attachmentAnchorData.anchorTransforms[i] };
+                anchorDataBuffer.AddRange(anchors);
+                anchors.Dispose();
+
+                NativeArray<GpuEcsCurrentAttachmentAnchorBufferElement> currentAnchorTransforms = new NativeArray<GpuEcsCurrentAttachmentAnchorBufferElement>(authoring.nbrOfAttachmentAnchors, Allocator.Temp);
+                currentAnchorTransformBuffer.AddRange(currentAnchorTransforms);
+                currentAnchorTransforms.Dispose();
+            }
+
+            AddBuffer<GpuEcsAnimatorEventBufferElement>(entity);
+        }
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorBehaviour.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 6dbd5b1412c14f19ba40d2188c5cd8c1
+timeCreated: 1678872649

+ 69 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorComponents.cs

@@ -0,0 +1,69 @@
+using Unity.Entities;
+using Unity.Mathematics;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    public struct GpuEcsAnimationDataComponent : IComponentData
+    {
+        public int totalNbrOfFrames;
+        public int nbrOfAttachmentAnchors;
+    }
+    public struct GpuEcsAnimationDataBufferElement : IBufferElementData
+    {
+        public int startFrameIndex;
+        public int nbrOfFramesPerSample;
+        public int nbrOfInBetweenSamples;
+        public float blendTimeCorrection;
+        public int startEventOccurenceId;
+        public int nbrOfEventOccurenceIds;
+        public bool loop;
+    }
+
+    public struct GpuEcsAnimationEventOccurenceBufferElement : IBufferElementData
+    {
+        public float eventNormalizedTime;
+        public int eventId;
+    }
+    
+    public struct GpuEcsAnimatorShaderDataComponent : IComponentData
+    {
+        public float4x4 shaderData;
+    }
+
+    public struct GpuEcsAnimatorInitializedComponent : IComponentData
+    {
+        public bool initialized;
+    }
+    
+    public struct GpuEcsAnimatorTransitionInfoComponent : IComponentData
+    {
+        public AnimatorInfo current;
+        public float blendPreviousToCurrent; // 0 when only previous is running, 1 when only current is running
+        public AnimatorInfo previous;
+    }
+
+    public struct GpuEcsAnimatorStateComponent : IComponentData
+    {
+        public float currentNormalizedTime;
+        public float previousNormalizedTime;
+        public bool stoppedCurrent;
+        public bool stoppedPrevious;
+    }
+
+    public struct GpuEcsAttachmentAnchorDataBufferElement : IBufferElementData
+    {
+        public float4x4 anchorTransform;
+    }
+    
+    public struct GpuEcsCurrentAttachmentAnchorBufferElement : IBufferElementData
+    {
+        public float4x4 currentTransform;
+    }
+    
+    public struct GpuEcsAnimatorEventBufferElement : IBufferElementData
+    {
+        public int animationId;
+        public int eventId;
+    }
+    
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorComponents.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 7c06f41bb0de4823a2384a594d94fd8c
+timeCreated: 1678872738

+ 30 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorControlComponents.cs

@@ -0,0 +1,30 @@
+using Unity.Entities;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    public struct GpuEcsAnimatorControlComponent : IComponentData
+    {
+        public AnimatorInfo animatorInfo; // All info about the animation you want to play
+        public float startNormalizedTime; // An option to start the animation from an arbitrary position (0 to 1)
+        public float transitionSpeed; // The transition speed that will be applied when switching to another animation
+    }
+
+    public struct AnimatorInfo
+    {
+        public int animationID; // the unique animation ID, can be assigned from the generated enum file
+        public float blendFactor; // From 0 to 1, going from clip1 to clip2
+        public float speedFactor; // <1 to make the animation go slower, >1 to make it go faster
+    }
+
+    public enum GpuEcsAnimatorControlStates
+    {
+        Start,
+        Stop,
+        KeepCurrentState
+    }
+
+    public struct GpuEcsAnimatorControlStateComponent : IComponentData
+    {
+        public GpuEcsAnimatorControlStates state;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorControlComponents.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: f12784a584374eb997d1a427f78a7285
+timeCreated: 1679578863

+ 26 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorInitializerBehaviour.cs

@@ -0,0 +1,26 @@
+using System;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    [RequireComponent(typeof(GpuEcsAnimatorBehaviour))]
+    public class GpuEcsAnimatorInitializerBehaviour : MonoBehaviour
+    {
+        public virtual int GetInitialAnimationID() { return 0; }
+    }
+
+    [RequireComponent(typeof(GpuEcsAnimatorBehaviour))]
+    public class GpuEcsAnimatorInitializerBehaviour<T> : GpuEcsAnimatorInitializerBehaviour where T : Enum
+    {
+        public T initialAnimationId;
+
+        public override int GetInitialAnimationID()
+        {
+            Array values = Enum.GetValues(typeof(T));
+            for (int i = 0; i < values.Length; i++)
+                if((values.GetValue(i)).Equals(initialAnimationId)) return i;
+            return 0;
+        }
+    }
+    
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorInitializerBehaviour.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: ec9958e85aff4d3da10f04e0d50d7a00
+timeCreated: 1679565423

+ 313 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorSystem.cs

@@ -0,0 +1,313 @@
+using GpuEcsAnimationBaker.Engine.Data;
+using Unity.Burst;
+using Unity.Collections;
+using Unity.Entities;
+using Unity.Mathematics;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    [BurstCompile]
+    public partial struct GpuEcsAnimatorSystem : ISystem
+    {
+        [BurstCompile]
+        public void OnUpdate(ref SystemState state)
+        {
+            EndSimulationEntityCommandBufferSystem.Singleton ecbSystem =
+                SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>();
+            EntityCommandBuffer.ParallelWriter ecb = ecbSystem.CreateCommandBuffer(state.WorldUnmanaged).AsParallelWriter();
+            float deltaTime = SystemAPI.Time.DeltaTime;
+            state.Dependency = new GpuEcsAnimatorJob()
+            {
+                ecb = ecb,
+                deltaTime = deltaTime
+            }.ScheduleParallel(state.Dependency);
+        }
+
+        [BurstCompile]
+        private partial struct GpuEcsAnimatorJob : IJobEntity
+        {
+            public EntityCommandBuffer.ParallelWriter ecb;
+            [ReadOnly] public float deltaTime;
+
+            public void Execute(
+                ref GpuEcsAnimatorShaderDataComponent gpuEcsAnimatorShaderData,
+                ref GpuEcsAnimatorTransitionInfoComponent gpuEcsAnimatorTransitionInfo,
+                ref GpuEcsAnimatorStateComponent gpuEcsAnimatorState,
+                ref GpuEcsAnimatorInitializedComponent gpuEcsAnimatorInitialized,
+                ref DynamicBuffer<GpuEcsCurrentAttachmentAnchorBufferElement> gpuEcsCurrentAttachmentAnchors,
+                ref GpuEcsAnimatorControlStateComponent gpuEcsAnimatorControlState,
+                ref DynamicBuffer<GpuEcsAnimatorEventBufferElement> gpuEcsAnimatorEventBuffer,
+                in GpuEcsAnimatorControlComponent gpuEcsAnimatorControl,
+                in GpuEcsAnimationDataComponent gpuEcsAnimationData,
+                in DynamicBuffer<GpuEcsAnimationDataBufferElement> gpuEcsAnimationDataBuffer,
+                in DynamicBuffer<GpuEcsAnimationEventOccurenceBufferElement> gpuEcsAnimationEventOccurenceBuffer,
+                in DynamicBuffer<GpuEcsAttachmentAnchorDataBufferElement> gpuEcsAttachmentAnchorData,
+                [ChunkIndexInQuery] int sortKey, Entity gpuEcsAnimatorEntity)
+            {
+                gpuEcsAnimatorEventBuffer.Clear();
+                if (!gpuEcsAnimatorInitialized.initialized )
+                {
+                    // We switch immediately to the first animation, no transition
+                    gpuEcsAnimatorTransitionInfo = new GpuEcsAnimatorTransitionInfoComponent()
+                    {
+                        current = gpuEcsAnimatorControl.animatorInfo,
+                        blendPreviousToCurrent = 1f
+                    };
+                    gpuEcsAnimatorState = new GpuEcsAnimatorStateComponent()
+                    {
+                        currentNormalizedTime = gpuEcsAnimatorControl.startNormalizedTime,
+                        stoppedPrevious = false,
+                        stoppedCurrent = false
+                    };
+                    gpuEcsAnimatorInitialized.initialized = true;
+                }
+                else if(gpuEcsAnimatorControl.animatorInfo.animationID != gpuEcsAnimatorTransitionInfo.current.animationID)
+                {
+                    // A new animation (or animation combination) has been started, so we need to do a transition
+                    // from the old one to the new
+                    gpuEcsAnimatorTransitionInfo = new GpuEcsAnimatorTransitionInfoComponent()
+                    {
+                        current = gpuEcsAnimatorControl.animatorInfo,
+                        previous = gpuEcsAnimatorTransitionInfo.current,
+                        blendPreviousToCurrent = 0f
+                    };
+                    gpuEcsAnimatorState = new GpuEcsAnimatorStateComponent()
+                    {
+                        previousNormalizedTime = gpuEcsAnimatorState.currentNormalizedTime,
+                        stoppedPrevious = gpuEcsAnimatorState.stoppedCurrent,
+                        currentNormalizedTime = gpuEcsAnimatorControl.startNormalizedTime,
+                        stoppedCurrent = false,
+                    };
+                }
+                else
+                {
+                    // The same animation (or animation combination) is still running, but the parameters might have changed
+                    // (blendPrimaryToSecondary or speedFactor)
+                    gpuEcsAnimatorTransitionInfo.current = gpuEcsAnimatorControl.animatorInfo;
+                }
+
+                GpuEcsAnimatorControlStates controlState = gpuEcsAnimatorControlState.state;
+                if (gpuEcsAnimatorControlState.state == GpuEcsAnimatorControlStates.Start)
+                    gpuEcsAnimatorState.stoppedCurrent = false;
+                else if (gpuEcsAnimatorControlState.state == GpuEcsAnimatorControlStates.Stop)
+                    gpuEcsAnimatorState.stoppedCurrent = true;
+                gpuEcsAnimatorControlState.state = GpuEcsAnimatorControlStates.KeepCurrentState;
+
+                if (!gpuEcsAnimatorState.stoppedCurrent)
+                {
+                    UpdateAnimatorState(ref gpuEcsAnimatorState.currentNormalizedTime, ref gpuEcsAnimatorState.stoppedCurrent,
+                        ref gpuEcsAnimatorEventBuffer,
+                        gpuEcsAnimatorTransitionInfo.current, controlState, gpuEcsAnimationDataBuffer, gpuEcsAnimationEventOccurenceBuffer,
+                        out float primaryBlendFactor, out float primaryTransitionToNextFrame, out int primaryFrameIndex,
+                        out float secondaryBlendFactor, out float secondaryTransitionToNextFrame, out int secondaryFrameIndex,
+                        sortKey, gpuEcsAnimatorEntity, forPrevious: false);
+                    if (gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent >= 1f)
+                    {
+                        gpuEcsAnimatorShaderData.shaderData = new float4x4(
+                            primaryBlendFactor, primaryTransitionToNextFrame, primaryFrameIndex, 0,
+                            secondaryBlendFactor, secondaryTransitionToNextFrame, secondaryFrameIndex, 0,
+                            0, 0, 0, 0,
+                            0, 0, 0, 0);
+
+                        //Apply attachment anchor transforms
+                        for (int attachmentAnchorIndex = 0; attachmentAnchorIndex < gpuEcsAnimationData.nbrOfAttachmentAnchors; attachmentAnchorIndex++)
+                        {
+                            int baseIndex = gpuEcsAnimationData.totalNbrOfFrames * attachmentAnchorIndex;
+                            gpuEcsCurrentAttachmentAnchors[attachmentAnchorIndex] = new GpuEcsCurrentAttachmentAnchorBufferElement()
+                            {
+                                currentTransform = LerpBlend(gpuEcsAttachmentAnchorData, baseIndex,
+                                    primaryFrameIndex, secondaryFrameIndex,
+                                    primaryTransitionToNextFrame, secondaryTransitionToNextFrame,
+                                    secondaryBlendFactor)
+                            };
+                        }
+                    }
+                    else
+                    {
+                        if (gpuEcsAnimatorControl.transitionSpeed == 0) gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent = 1f;
+                        else
+                        {
+                            gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent += deltaTime / gpuEcsAnimatorControl.transitionSpeed;
+                            if (gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent > 1f) gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent = 1f;
+                        }
+
+                        float previousToCurrent = gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent;
+                        float currentToPrevious = 1f - previousToCurrent;
+                        UpdateAnimatorState(ref gpuEcsAnimatorState.previousNormalizedTime, ref gpuEcsAnimatorState.stoppedPrevious,
+                            ref gpuEcsAnimatorEventBuffer,
+                            gpuEcsAnimatorTransitionInfo.previous, controlState, gpuEcsAnimationDataBuffer, gpuEcsAnimationEventOccurenceBuffer,
+                            out float previousPrimaryBlendFactor, out float previousPrimaryTransitionToNextFrame, out int previousPrimaryFrameIndex,
+                            out float previousSecondaryBlendFactor, out float previousSecondaryTransitionToNextFrame, out int previousSecondaryFrameIndex,
+                            sortKey, gpuEcsAnimatorEntity, forPrevious: true);
+
+                        gpuEcsAnimatorShaderData.shaderData = new float4x4(
+                            previousToCurrent * primaryBlendFactor, primaryTransitionToNextFrame, primaryFrameIndex, 0,
+                            previousToCurrent * secondaryBlendFactor, secondaryTransitionToNextFrame, secondaryFrameIndex, 0,
+                            currentToPrevious * previousPrimaryBlendFactor, previousPrimaryTransitionToNextFrame, previousPrimaryFrameIndex, 0,
+                            currentToPrevious * previousSecondaryBlendFactor, previousSecondaryTransitionToNextFrame, previousSecondaryFrameIndex, 0);
+
+                        for (int attachmentAnchorIndex = 0; attachmentAnchorIndex < gpuEcsAnimationData.nbrOfAttachmentAnchors; attachmentAnchorIndex++)
+                        {
+                            int baseIndex = gpuEcsAnimationData.totalNbrOfFrames * attachmentAnchorIndex;
+
+                            float4x4 current = LerpBlend(gpuEcsAttachmentAnchorData, baseIndex,
+                                primaryFrameIndex, secondaryFrameIndex,
+                                primaryTransitionToNextFrame, secondaryTransitionToNextFrame,
+                                secondaryBlendFactor);
+                            float4x4 previous = LerpBlend(gpuEcsAttachmentAnchorData, baseIndex,
+                                previousPrimaryFrameIndex, previousSecondaryFrameIndex,
+                                previousPrimaryTransitionToNextFrame, previousSecondaryTransitionToNextFrame,
+                                previousSecondaryBlendFactor);
+
+                            gpuEcsCurrentAttachmentAnchors[attachmentAnchorIndex] = new GpuEcsCurrentAttachmentAnchorBufferElement()
+                            {
+                                currentTransform = LerpTransform(previous, current, previousToCurrent)
+                            };
+                        }
+                    }
+                }
+            }
+            
+            private float4x4 LerpBlend(in DynamicBuffer<GpuEcsAttachmentAnchorDataBufferElement> gpuEcsAttachmentAnchorData,
+                int baseIndex, int frameIndexA, int frameIndexB, 
+                float frameIndexATransitionToNextFrame, float frameIndexBTransitionToNextFrame,
+                float t)
+            {
+                float4x4 result;
+                if (t == 0)
+                    result = LerpNextFrame(gpuEcsAttachmentAnchorData, baseIndex, frameIndexA, frameIndexATransitionToNextFrame);
+                else if(t == 1f)
+                    result = LerpNextFrame(gpuEcsAttachmentAnchorData, baseIndex, frameIndexB, frameIndexBTransitionToNextFrame);
+                else
+                {
+                    float4x4 primary = LerpNextFrame(gpuEcsAttachmentAnchorData, baseIndex, frameIndexA, frameIndexATransitionToNextFrame);
+                    float4x4 secondary = LerpNextFrame(gpuEcsAttachmentAnchorData, baseIndex, frameIndexB, frameIndexBTransitionToNextFrame);
+                    result = LerpTransform(primary, secondary, t); 
+                }
+                return result;
+            }
+
+            private float4x4 LerpNextFrame(in DynamicBuffer<GpuEcsAttachmentAnchorDataBufferElement> gpuEcsAttachmentAnchorData,
+                int baseIndex, int frameIndex, float transitionToNextFrame)
+            {
+                return LerpTransform(
+                    gpuEcsAttachmentAnchorData[baseIndex + frameIndex].anchorTransform,
+                    gpuEcsAttachmentAnchorData[baseIndex + frameIndex + 1].anchorTransform,
+                    transitionToNextFrame
+                );
+            }
+
+            private float4x4 LerpTransform(float4x4 valueA, float4x4 valueB, float t)
+            {
+                float3 posA = new float3(valueA.c3.x, valueA.c3.y, valueA.c3.z);
+                quaternion rotA = new quaternion(valueA);
+                float3 posB = new float3(valueB.c3.x, valueB.c3.y, valueB.c3.z);
+                quaternion rotB = new quaternion(valueB);
+
+                float3 pos = math.lerp(posA, posB, t);
+                Quaternion rot = math.slerp(rotA, rotB, t);
+                return float4x4.TRS(pos, rot, new float3(1f, 1f, 1f));
+            }
+
+            private void UpdateAnimatorState(ref float normalizedTime, ref bool stopped, 
+                ref DynamicBuffer<GpuEcsAnimatorEventBufferElement> gpuEcsAnimatorEventBuffer,
+                AnimatorInfo animatorInfo,
+                in GpuEcsAnimatorControlStates controlState,
+                in DynamicBuffer<GpuEcsAnimationDataBufferElement> gpuEcsAnimationDataBuffer,
+                in DynamicBuffer<GpuEcsAnimationEventOccurenceBufferElement> gpuEcsAnimationEventOccurenceBuffer,
+                out float primaryBlendFactor, out float primaryTransitionToNextFrame, out int primaryFrameIndex,
+                out float secondaryBlendFactor, out float secondaryTransitionToNextFrame, out int secondaryFrameIndex,
+                in int sortKey, Entity gpuEcsAnimatorEntity, bool forPrevious)
+            {
+                GpuEcsAnimationDataBufferElement animationData = gpuEcsAnimationDataBuffer[animatorInfo.animationID];
+
+                if (animationData.nbrOfInBetweenSamples == 1)
+                {
+                    float blendSpeedAdjustment = 1f;
+                    UpdateAnimationNormalizedTime(ref normalizedTime, ref stopped, ref gpuEcsAnimatorEventBuffer, animatorInfo, controlState, 
+                        gpuEcsAnimationEventOccurenceBuffer, animationData, blendSpeedAdjustment, 
+                        out float transitionToNextFrame, out int relativeFrameIndex, sortKey, gpuEcsAnimatorEntity, forPrevious);
+                    primaryBlendFactor = 1;
+                    primaryTransitionToNextFrame = transitionToNextFrame;
+                    primaryFrameIndex = animationData.startFrameIndex + relativeFrameIndex;
+                    secondaryBlendFactor = 0;
+                    secondaryTransitionToNextFrame = 0;
+                    secondaryFrameIndex = 0;
+                }
+                else
+                {
+                    float endBlend = (float)(animationData.nbrOfInBetweenSamples - 1);
+                    float currentBlendSetFloat = animatorInfo.blendFactor * endBlend;
+                    int currentBlendSet = (int)math.floor(currentBlendSetFloat);
+                    float transitionToNextSet = currentBlendSetFloat - (float)currentBlendSet;
+                    
+                    float blendSpeedAdjustment = animatorInfo.blendFactor * animationData.blendTimeCorrection + (1f - animatorInfo.blendFactor);
+                    UpdateAnimationNormalizedTime(ref normalizedTime, ref stopped, ref gpuEcsAnimatorEventBuffer, animatorInfo, controlState, 
+                        gpuEcsAnimationEventOccurenceBuffer, animationData, blendSpeedAdjustment, 
+                        out float transitionToNextFrame, out int relativeFrameIndex, sortKey, gpuEcsAnimatorEntity, forPrevious);
+                    primaryBlendFactor = 1f - transitionToNextSet;
+                    primaryTransitionToNextFrame = transitionToNextFrame;
+                    primaryFrameIndex = animationData.startFrameIndex + currentBlendSet * animationData.nbrOfFramesPerSample + relativeFrameIndex;
+                    secondaryBlendFactor = transitionToNextSet;
+                    secondaryTransitionToNextFrame = transitionToNextFrame;
+                    secondaryFrameIndex = animationData.startFrameIndex + (currentBlendSet + 1) * animationData.nbrOfFramesPerSample + relativeFrameIndex;
+                }
+            }
+
+            private void UpdateAnimationNormalizedTime(ref float normalizedTime, ref bool stopped,
+                ref DynamicBuffer<GpuEcsAnimatorEventBufferElement> gpuEcsAnimatorEventBuffer,
+                AnimatorInfo animatorInfo, in GpuEcsAnimatorControlStates controlState,
+                in DynamicBuffer<GpuEcsAnimationEventOccurenceBufferElement> gpuEcsAnimationEventOccurenceBuffer,
+                GpuEcsAnimationDataBufferElement animationData, float blendSpeedAdjustment, 
+                out float transitionToNextFrame, out int relativeFrameIndex, int sortKey, Entity gpuEcsAnimatorEntity, bool forPrevious)
+            {
+                int endFrame = animationData.nbrOfFramesPerSample - 1;
+                float animationLength = (float)endFrame / GlobalConstants.SampleFrameRate;
+                float currentTime = normalizedTime * animationLength;
+                if(!stopped) currentTime += deltaTime * animatorInfo.speedFactor * blendSpeedAdjustment;
+                float normalizedTimeLastUpdate = normalizedTime;
+                normalizedTime = currentTime / animationLength;
+                
+                for (int eventOccurencId = animationData.startEventOccurenceId; eventOccurencId < animationData.startEventOccurenceId + animationData.nbrOfEventOccurenceIds; eventOccurencId++)
+                {
+                    GpuEcsAnimationEventOccurenceBufferElement occurence = gpuEcsAnimationEventOccurenceBuffer[eventOccurencId];
+                    if (normalizedTimeLastUpdate < occurence.eventNormalizedTime && normalizedTime > occurence.eventNormalizedTime)
+                    {
+                        //Trigger event
+                        gpuEcsAnimatorEventBuffer.Add(new GpuEcsAnimatorEventBufferElement()
+                        {
+                            animationId = animatorInfo.animationID,
+                            eventId = occurence.eventId
+                        });
+                    }
+                }
+
+                if (!forPrevious && (animationData.loop || controlState == GpuEcsAnimatorControlStates.Start))
+                {
+                    while (normalizedTime >= 1f) normalizedTime -= 1f;
+                }
+                else
+                {
+                    if (normalizedTime >= 1f)
+                    {
+                        normalizedTime = 1f;
+                        stopped = true;
+                    }
+                }
+
+                if (normalizedTime == 1f) 
+                {
+                    relativeFrameIndex = endFrame - 1;
+                    transitionToNextFrame = 1f;
+                }
+                else
+                {
+                    float relativeFrameIndexFloat = normalizedTime * (float)endFrame;
+                    relativeFrameIndex = (int)math.floor(relativeFrameIndexFloat);
+                    transitionToNextFrame = relativeFrameIndexFloat - (float)relativeFrameIndex;
+                }
+            }
+        }
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAnimatorSystem.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 49919f8307c64e1295ff28ed06574630
+timeCreated: 1678957246

+ 12 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentAnchorData.cs

@@ -0,0 +1,12 @@
+using System;
+using Unity.Mathematics;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    [Serializable]
+    public class GpuEcsAttachmentAnchorData : ScriptableObject
+    {
+        public float4x4[] anchorTransforms;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentAnchorData.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: f9f8288587a245c68a88b9c4a4a3b09a
+timeCreated: 1691945420

+ 37 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentBehaviour.cs

@@ -0,0 +1,37 @@
+using Unity.Entities;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    public class GpuEcsAttachmentBehaviour : MonoBehaviour
+    {
+    }
+    
+    public class GpuEcsAttachmentBaker : Baker<GpuEcsAttachmentBehaviour>
+    {
+        public override void Bake(GpuEcsAttachmentBehaviour authoring)
+        {
+            int attachmentAnchorId = 0;
+            Entity gpuEcsAnimatorEntity = Entity.Null;
+            
+            GpuEcsAttachmentInitializerBehaviour initializer = authoring.GetComponent<GpuEcsAttachmentInitializerBehaviour>();
+            if (initializer != null) attachmentAnchorId = initializer.GetAttachmentAnchorID();
+            if (authoring.transform.parent != null)
+            {
+                GpuEcsAnimatorBehaviour gpuEcsAnimator = authoring.transform.parent.GetComponent<GpuEcsAnimatorBehaviour>();
+                if (gpuEcsAnimator != null)
+                {
+                    gpuEcsAnimatorEntity = GetEntity(gpuEcsAnimator, TransformUsageFlags.None);
+                }
+            }
+
+            Entity entity = GetEntity(TransformUsageFlags.Dynamic);
+            AddComponent(entity, new GpuEcsAttachmentComponent()
+            {
+                gpuEcsAnimatorEntity = gpuEcsAnimatorEntity,
+                attachmentAnchorId = attachmentAnchorId
+            });
+            
+        }
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentBehaviour.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 18dcb30678534d95a256d194d2fe8b33
+timeCreated: 1692011427

+ 10 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentComponents.cs

@@ -0,0 +1,10 @@
+using Unity.Entities;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    public struct GpuEcsAttachmentComponent : IComponentData
+    {
+        public Entity gpuEcsAnimatorEntity;
+        public int attachmentAnchorId;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentComponents.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 8f4c26e1dc68431184503c832f9e61c3
+timeCreated: 1692011148

+ 25 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentInitializerBehaviour.cs

@@ -0,0 +1,25 @@
+using System;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    [RequireComponent(typeof(GpuEcsAttachmentBehaviour))]
+    public class GpuEcsAttachmentInitializerBehaviour : MonoBehaviour
+    {
+        public virtual int GetAttachmentAnchorID() { return 0; }
+    }
+
+    [RequireComponent(typeof(GpuEcsAttachmentBehaviour))]
+    public class GpuEcsAttachmentInitializerBehaviour<T> : GpuEcsAttachmentInitializerBehaviour where T : Enum
+    {
+        public T attachmentAnchorId;
+
+        public override int GetAttachmentAnchorID()
+        {
+            Array values = Enum.GetValues(typeof(T));
+            for (int i = 0; i < values.Length; i++)
+                if((values.GetValue(i)).Equals(attachmentAnchorId)) return i;
+            return 0;
+        }
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentInitializerBehaviour.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 241ce774393b43d5bf0d05b28c882d5a
+timeCreated: 1692094783

+ 43 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentSystem.cs

@@ -0,0 +1,43 @@
+using Unity.Burst;
+using Unity.Collections;
+using Unity.Entities;
+using Unity.Transforms;
+
+namespace GPUECSAnimationBaker.Engine.AnimatorSystem
+{
+    [BurstCompile]
+    public partial struct GpuEcsAttachmentSystem : ISystem
+    {
+        private BufferLookup<GpuEcsCurrentAttachmentAnchorBufferElement> gpuEcsCurrentAttachmentAnchorLookup;
+        
+        [BurstCompile]
+        public void OnCreate(ref SystemState state)
+        {
+            gpuEcsCurrentAttachmentAnchorLookup = state.GetBufferLookup<GpuEcsCurrentAttachmentAnchorBufferElement>(isReadOnly: true);
+        }
+        
+        [BurstCompile]
+        public void OnUpdate(ref SystemState state)
+        {
+            gpuEcsCurrentAttachmentAnchorLookup.Update(ref state);
+            state.Dependency = new GpuEcsAttachmentJob()
+            {
+                gpuEcsCurrentAttachmentAnchorLookup = gpuEcsCurrentAttachmentAnchorLookup
+            }.ScheduleParallel(state.Dependency);
+        }
+
+        [BurstCompile]
+        private partial struct GpuEcsAttachmentJob : IJobEntity
+        {
+            [ReadOnly] public BufferLookup<GpuEcsCurrentAttachmentAnchorBufferElement> gpuEcsCurrentAttachmentAnchorLookup;
+            
+            public void Execute(ref LocalTransform localTransform, in GpuEcsAttachmentComponent gpuEcsAttachment)
+            {
+                DynamicBuffer<GpuEcsCurrentAttachmentAnchorBufferElement> currentAttachmentAnchors 
+                    = gpuEcsCurrentAttachmentAnchorLookup[gpuEcsAttachment.gpuEcsAnimatorEntity];
+                GpuEcsCurrentAttachmentAnchorBufferElement currentAnchor = currentAttachmentAnchors[gpuEcsAttachment.attachmentAnchorId];
+                localTransform = LocalTransform.FromMatrix(currentAnchor.currentTransform);
+            }
+        }
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/AnimatorSystem/GpuEcsAttachmentSystem.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: ef7fb8eb346843f393c9a6f812fed55e
+timeCreated: 1692012598

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Baker.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 396ecc82f4964a3f94db7e59a6afcdf3
+timeCreated: 1678870574

+ 832 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakeServices.cs

@@ -0,0 +1,832 @@
+#if UNITY_EDITOR
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using GPUECSAnimationBaker.Engine.AnimatorSystem;
+using GpuEcsAnimationBaker.Engine.Data;
+using Unity.Collections;
+using Unity.Mathematics;
+using UnityEditor;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.Baker
+{
+    public static class GpuEcsAnimationBakerServices
+    {
+        private static readonly int AnimatedBoneMatrices = Shader.PropertyToID("_AnimatedBoneMatrices");
+        private static readonly int EnableAnimation = Shader.PropertyToID("_EnableAnimation");
+
+        public static bool ValidateAnimationBakerData(GpuEcsAnimationBakerData bakerData, GameObject sourceModel, out string errors)
+        {
+            StringBuilder sbErrors = new StringBuilder();
+            if (bakerData.animations.Length == 0)
+                sbErrors.AppendLine("At least one animation must be baked.");
+
+            foreach (AnimationData animation in bakerData.animations)
+            {
+                if (string.IsNullOrWhiteSpace(animation.animationID))
+                    sbErrors.AppendLine("Animation ID is mandatory");
+                if (!Regex.IsMatch(animation.animationID, @"^[a-zA-Z_][a-zA-Z0-9_]+$"))
+                    sbErrors.AppendLine("Animation ID must be only letters, numbers or underscore, must not start with number");
+                if (string.IsNullOrWhiteSpace(animation.animatorStateName))
+                    sbErrors.AppendLine("Animation State Name is mandatory");
+                if (animation.animationType == AnimationTypes.SingleClip)
+                {
+                    if (animation.singleClipData.animationClip == null)
+                        sbErrors.AppendLine("Animation Clip is mandatory");
+                }
+                else if (animation.animationType == AnimationTypes.DualClipBlend)
+                {
+                    if (string.IsNullOrWhiteSpace(animation.dualClipBlendData.blendParameterName))
+                        sbErrors.AppendLine("Blend parameter name is mandatory");
+                    if (animation.dualClipBlendData.clip1.animationClip == null)
+                        sbErrors.AppendLine("Animation Clip 1 is mandatory");
+                    if (animation.dualClipBlendData.clip1.animationClip == null)
+                        sbErrors.AppendLine("Animation Clip 2 is mandatory");
+                    if (animation.dualClipBlendData.nbrOfInBetweenSamples < 2)
+                        sbErrors.AppendLine("Nbr of in between samples must be at least 2");
+                    if (animation.dualClipBlendData.nbrOfInBetweenSamples > 100)
+                        sbErrors.AppendLine("Nbr of in between samples is maximum 100");
+                }
+
+                foreach (AnimatorParameter parameterValue in animation.additionalAnimatorParameterValues)
+                {
+                    if (string.IsNullOrWhiteSpace(parameterValue.parameterName))
+                        sbErrors.AppendLine("Additional animator parameter name is mandatory");
+                }
+            }
+
+            bool foundDouble = false;
+            for (int i = 0; i < bakerData.animations.Length; i++)
+            {
+                for (int j = i + 1; j < bakerData.animations.Length; j++)
+                {
+                    if (bakerData.animations[i].animationID == bakerData.animations[j].animationID)
+                    {
+                        foundDouble = true; break;
+                    }
+                }
+                if(foundDouble) break;
+            }
+            if(foundDouble) sbErrors.AppendLine("Animation IDs must be unique");
+
+            foreach (AttachmentAnchor attachmentAnchor in bakerData.attachmentAnchors)
+            {
+                if (string.IsNullOrWhiteSpace(attachmentAnchor.attachmentAnchorID))
+                    sbErrors.AppendLine("Attachment Anchor ID is mandatory");
+                if(attachmentAnchor.attachmentAnchorTransform == null)
+                    sbErrors.AppendLine("Attachment Anchor reference transform is mandatory");
+                else if(!hasParent(attachmentAnchor.attachmentAnchorTransform, sourceModel.transform))
+                    sbErrors.AppendLine($"Attachment Anchor reference transform must be nested inside {sourceModel.name}");
+            }
+            
+            if(bakerData.boneUsage.numberOfBonesPerVertex < 1) 
+                sbErrors.AppendLine("Nbr of bones per vertex must be at least 1");
+            foreach (BoneUsagePerLoD boneUsagePerLOD in bakerData.boneUsage.boneUsagesPerLoD)
+            {
+                if(boneUsagePerLOD.maxNumberOfBonesPerVertex < 1) 
+                    sbErrors.AppendLine("Nbr of bones per vertex must be at least 1");
+            }
+            
+            errors = sbErrors.ToString();
+            return sbErrors.Length == 0;
+        }
+
+        private static bool hasParent(Transform child, Transform parent)
+        {
+            if (child.parent == null) return false;
+            if (child.parent.gameObject == parent.gameObject) return true;
+            else return hasParent(child.parent, parent);
+        }
+
+        public static GameObject GenerateAnimationObject(string assetPath, 
+            GpuEcsAnimationBakerData bakerData, string animatorName, string generatedAssetsFolder, 
+            string nameSuffixAsset = "_GpuEcsAnimator",
+            string nameSuffixAnimationIDsEnum = "_AnimationIDs",
+            string nameSuffixAnimationInitializerBehaviour = "_AnimationInitializerBehaviour",
+            string nameSuffixAnimationEventIDsEnum = "_AnimationEventIDs",
+            string nameSuffixAnimationAnchorIDsEnum = "_AttachmentAnchorIDs",
+            string nameSuffixAttachmentInitializerBehaviour = "_AttachmentInitializerBehaviour",
+            string meshPartSuffix = "Mesh",
+            string animationMatricesTexturePartSuffix = "AnimationMatricesTexture", 
+            string materialPartSuffix = "Material"
+            )
+        {
+            GameObject sourceModel = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
+            GameObject refModel = PrefabUtility.LoadPrefabContents(assetPath);
+
+            Debug.Log($"Generating Animation object for {assetPath}");
+            GameObject animationObject = GenerateAnimationObjectFromModel(refModel, sourceModel, bakerData, animatorName, generatedAssetsFolder,
+                nameSuffixAsset, nameSuffixAnimationIDsEnum, nameSuffixAnimationInitializerBehaviour, nameSuffixAnimationEventIDsEnum,
+                nameSuffixAnimationAnchorIDsEnum, nameSuffixAttachmentInitializerBehaviour, meshPartSuffix, animationMatricesTexturePartSuffix, materialPartSuffix);
+            PrefabUtility.UnloadPrefabContents(refModel);
+            
+            return animationObject;
+        }
+        
+        public static GameObject GenerateAnimationObjectFromModel(GameObject refModel, GameObject sourceModel, 
+            GpuEcsAnimationBakerData bakerData, string animatorName, string generatedAssetsFolder,
+            string nameSuffixAsset = "_GpuEcsAnimator",
+            string nameSuffixAnimationIDsEnum = "_AnimationIDs",
+            string nameSuffixAnimationInitializerBehaviour = "_AnimationInitializerBehaviour",
+            string nameSuffixAnimationEventIDsEnum = "_AnimationEventIDs",
+            string nameSuffixAnimationAnchorIDsEnum = "_AttachmentAnchorIDs",
+            string nameSuffixAttachmentInitializerBehaviour = "_AttachmentInitializerBehaviour",
+            string meshPartSuffix = "Mesh",
+            string animationMatricesTexturePartSuffix = "AnimationMatricesTexture", 
+            string materialPartSuffix = "Material"
+            ) 
+        {
+            if(!ValidateAnimationBakerData(bakerData, sourceModel, out string errors))
+            {
+                Debug.LogError(errors);
+                return null;
+            }
+
+            string targetAssetPath =
+                Path.Combine(generatedAssetsFolder, $"{animatorName}{nameSuffixAsset}.prefab");
+            string targetAnimationEnumAssetPath =
+                Path.Combine(generatedAssetsFolder, $"{animatorName}{nameSuffixAnimationIDsEnum}.cs");
+            string targetAnimationInitializerBehaviourAssetPath =
+                Path.Combine(generatedAssetsFolder, $"{animatorName}{nameSuffixAnimationInitializerBehaviour}.cs");
+            string targetAnimationEventEnumAssetPath =
+                Path.Combine(generatedAssetsFolder, $"{animatorName}{nameSuffixAnimationEventIDsEnum}.cs");
+            string targetAttachmentAnchorEnumAssetPath =
+                Path.Combine(generatedAssetsFolder, $"{animatorName}{nameSuffixAnimationAnchorIDsEnum}.cs");
+            string targetAttachmentInitializerBehaviourAssetPath =
+                Path.Combine(generatedAssetsFolder, $"{animatorName}{nameSuffixAttachmentInitializerBehaviour}.cs");
+            
+            refModel.transform.position = Vector3.zero;
+            refModel.transform.rotation = quaternion.identity;
+            Animator refModelAnimator = refModel.GetComponent<Animator>();
+            refModelAnimator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
+            LODGroup refModelLoDGroup = refModel.GetComponent<LODGroup>();
+            LOD[] refModelLoDs = refModelLoDGroup == null ? null : refModelLoDGroup.GetLODs();
+            List<AnimationMatricesTexture> animationMatricesTexturesCache = new List<AnimationMatricesTexture>();
+            List<EcsGpuMaterial> ecsGpuMaterialsCache = new List<EcsGpuMaterial>();
+
+            GameObject test = AssetDatabase.LoadAssetAtPath<GameObject>(targetAssetPath);
+            if (test == null)
+            {
+                GameObject empty = new GameObject(refModel.name);
+                PrefabUtility.SaveAsPrefabAsset(empty, targetAssetPath);
+                GameObject.DestroyImmediate(empty, allowDestroyingAssets:true);
+            }
+            GameObject target = PrefabUtility.LoadPrefabContents(targetAssetPath);
+            target.transform.localScale = refModel.transform.localScale;
+            GameObject[] toDestroy = new GameObject[target.transform.childCount];
+            for (int childIndex = 0; childIndex < target.transform.childCount; childIndex++)
+                toDestroy[childIndex] = target.transform.GetChild(childIndex).gameObject;
+            foreach(GameObject go in toDestroy) Object.DestroyImmediate(go, allowDestroyingAssets: true);
+            RemoveComponent<MeshRenderer>(target);
+            RemoveComponent<MeshFilter>(target);
+            RemoveComponent<LODGroup>(target);
+            RemoveComponent<GpuEcsAnimatorBehaviour>(target);
+            RemoveComponent<GpuEcsAnimatedMeshBehaviour>(target);
+            
+            GpuEcsAnimatorBehaviour gpuEcsAnimator = AddGpuEcsAnimationBehaviour(target, bakerData, out string[] eventNames);
+            gpuEcsAnimator.transformUsageFlags = bakerData.transformUsageFlagsParent;
+
+            Dictionary<GameObject, GameObject> sourceToTargetMapping = new Dictionary<GameObject, GameObject>();
+            ProcessAnimationObjectRecursive(refModel, target, sourceToTargetMapping, animatorName,
+                meshPartSuffix, animationMatricesTexturePartSuffix, materialPartSuffix,
+                refModelAnimator, refModelLoDs, animationMatricesTexturesCache, ecsGpuMaterialsCache,
+                bakerData, gpuEcsAnimator.animations, gpuEcsAnimator.totalNbrOfFrames, generatedAssetsFolder, gpuEcsAnimator);
+            if (refModelLoDs != null)
+            {
+                LODGroup targetLoDGroup = target.AddComponent<LODGroup>();
+                LOD[] targetLoDs = new LOD[refModelLoDs.Length];
+                for (int lodIndex = 0; lodIndex < refModelLoDs.Length; lodIndex++)
+                {
+                    targetLoDs[lodIndex] = refModelLoDs[lodIndex];
+                    Renderer[] refModelRenderers = refModelLoDs[lodIndex].renderers;
+                    for (int rendererIndex = 0; rendererIndex < refModelRenderers.Length; rendererIndex++)
+                    {
+                        targetLoDs[lodIndex].renderers[rendererIndex] =
+                            sourceToTargetMapping[refModelRenderers[rendererIndex].gameObject].GetComponent<MeshRenderer>();
+                    }
+                }
+                targetLoDGroup.SetLODs(targetLoDs);
+            }
+            
+            if(bakerData.generateAnimationIdsEnum)
+                GenerateAnimationsEnumCode(bakerData, targetAnimationEnumAssetPath, targetAnimationInitializerBehaviourAssetPath);
+            
+            if(bakerData.generateAnimationEventIdsEnum)
+                GenerateAnimationEventsEnumCode(bakerData, targetAnimationEventEnumAssetPath, eventNames );
+
+            gpuEcsAnimator.nbrOfAttachmentAnchors = bakerData.attachmentAnchors.Length;
+            gpuEcsAnimator.attachmentAnchorData = BakeAttachmentAnchorTransforms(generatedAssetsFolder, sourceModel, animatorName, 
+                refModelAnimator, bakerData, gpuEcsAnimator.animations, gpuEcsAnimator.totalNbrOfFrames);
+            
+            if(bakerData.generateAttachmentAnchorIdsEnum)
+                GenerateAttachmentAnchorsEnumCode(bakerData, targetAttachmentAnchorEnumAssetPath, targetAttachmentInitializerBehaviourAssetPath);
+            
+            PrefabUtility.SaveAsPrefabAsset(target, targetAssetPath);
+            PrefabUtility.UnloadPrefabContents(target);
+            
+            return AssetDatabase.LoadAssetAtPath<GameObject>(targetAssetPath);
+        }
+
+        private const string enumFileTemplate = "namespace GPUECSAnimationBaker.Engine.AnimatorSystem\n"
+                                                + "{\n"
+                                                + "    public enum @ENUMNAME@\n"
+                                                + "    {\n"
+                                                + "@IDLIST@\n"
+                                                + "    }\n"
+                                                + "}";
+
+        private const string behaviourFileTemplate = "namespace GPUECSAnimationBaker.Engine.AnimatorSystem\n"
+                                                + "{\n"
+                                                + "    public class @CLASSNAME_@ENUMNAME@_Behaviour : @CLASSNAMEBehaviour<@ENUMNAME@> { } \n"
+                                                + "}";
+        
+        private static void GenerateAnimationsEnumCode(GpuEcsAnimationBakerData bakerData, string targetEnumAssetPath, string targetEnumBehaviourAssetPath)
+        {
+            GenerateEnumCodeFiles<AnimationData>($"AnimationIds{bakerData.animationIdsEnumName}", "GpuEcsAnimatorInitializer",
+                bakerData.animations, (animationData) => animationData.animationID, targetEnumAssetPath, targetEnumBehaviourAssetPath);
+        }
+
+        private static void GenerateAnimationEventsEnumCode(GpuEcsAnimationBakerData bakerData, string targetEnumAssetPath, string[] eventNames)
+        {
+            GenerateEnumCodeFiles<string>($"AnimationEventIds{bakerData.animationEventIdsEnumName}", null,
+                eventNames, (name) => name, targetEnumAssetPath, null);
+        }
+        
+        private static void GenerateAttachmentAnchorsEnumCode(GpuEcsAnimationBakerData bakerData, string targetEnumAssetPath, string targetEnumBehaviourAssetPath)
+        {
+            GenerateEnumCodeFiles<AttachmentAnchor>($"AnchorIds{bakerData.attachmentAnchorIdsEnumName}", "GpuEcsAttachmentInitializer", 
+                bakerData.attachmentAnchors, (attachmentAnchor) => attachmentAnchor.attachmentAnchorID, targetEnumAssetPath, targetEnumBehaviourAssetPath);
+        }
+        
+        private static void GenerateEnumCodeFiles<T>(string enumName, string className, T[] list, System.Func<T, string> listIdGetter, 
+            string targetEnumAssetPath, string targetEnumBehaviourAssetPath)
+        {
+            StringBuilder idList = new StringBuilder();
+            for (int index = 0; index < list.Length; index++)
+            {
+                idList.Append($"        {listIdGetter(list[index])} = {index.ToString()}");
+                if (index < list.Length - 1)
+                {
+                    idList.AppendLine(",");
+                }
+            }
+            
+            string enumCodeText = enumFileTemplate
+                .Replace("@ENUMNAME@", enumName)
+                .Replace("@IDLIST@", idList.ToString());
+            string enumCodePath = Path.Combine(Application.dataPath, "../" + targetEnumAssetPath); 
+            File.WriteAllText(enumCodePath, enumCodeText);
+
+            if (targetEnumBehaviourAssetPath != null)
+            {
+                string enumBehaviourText = behaviourFileTemplate
+                    .Replace("@CLASSNAME", className)
+                    .Replace("@ENUMNAME@", enumName);
+                string enumBehaviourPath = Path.Combine(Application.dataPath, "../" + targetEnumBehaviourAssetPath);
+                File.WriteAllText(enumBehaviourPath, enumBehaviourText);
+            }
+
+            AssetDatabase.Refresh();
+        }
+
+        private static GpuEcsAnimatorBehaviour AddGpuEcsAnimationBehaviour(GameObject target,
+            GpuEcsAnimationBakerData bakerData, out string[] eventNames)
+        {
+            GpuEcsAnimatorBehaviour gpuEcsAnimator = target.AddComponent<GpuEcsAnimatorBehaviour>();
+            gpuEcsAnimator.animations = new GpuEcsAnimationData[bakerData.animations.Length];
+            // gpuEcsAnimator.BackAnimationDatas= new AnimationData[bakerData.animations.Length];
+            List<GpuEcsAnimationEventOccurence> occurences = new List<GpuEcsAnimationEventOccurence>();
+            List<string> foundEvents = new List<string>();
+
+            int currentFrameIndex = 0;
+            int currentEventOccurenceId = 0;
+            int currentFoundEventId = 0;
+            for (int animationIndex = 0; animationIndex < bakerData.animations.Length; animationIndex++)
+            {
+                AnimationData animationData = bakerData.animations[animationIndex];
+                int nbrOfFramesPerSample = 0;
+                int nbrOfInBetweenSamples = 0;
+                float blendTimeCorrection = 1;
+                int startEventOccurenceId = currentEventOccurenceId;
+                int nbrOfEventOccurenceIds = 0;
+                if (animationData.animationType == AnimationTypes.SingleClip)
+                {
+                    SingleClipData singleClipData = animationData.singleClipData;
+                    nbrOfFramesPerSample = (int)(singleClipData.animationClip.length * GlobalConstants.SampleFrameRate) + 1;
+                    nbrOfInBetweenSamples = 1;
+                    blendTimeCorrection = 1;
+                    AddAnimationEvents(bakerData, animationData, occurences, ref currentEventOccurenceId, ref nbrOfEventOccurenceIds, foundEvents, 
+                        ref currentFoundEventId, singleClipData.animationClip);
+                }
+                else if (animationData.animationType == AnimationTypes.DualClipBlend)
+                {
+                    DualClipBlendData dualClipBlendData = animationData.dualClipBlendData;
+                    int clip1NbrOfFrames = (int)(dualClipBlendData.clip1.animationClip.length * GlobalConstants.SampleFrameRate) + 1;
+                    int clip2NbrOfFrames = (int)(dualClipBlendData.clip2.animationClip.length * GlobalConstants.SampleFrameRate) + 1;
+                    nbrOfFramesPerSample = math.max(clip1NbrOfFrames, clip2NbrOfFrames);
+                    blendTimeCorrection = dualClipBlendData.clip1.animationClip.length / dualClipBlendData.clip2.animationClip.length;
+                    nbrOfInBetweenSamples = dualClipBlendData.nbrOfInBetweenSamples;
+                    AddAnimationEvents(bakerData, animationData, occurences, ref currentEventOccurenceId, ref nbrOfEventOccurenceIds, foundEvents, 
+                        ref currentFoundEventId, dualClipBlendData.clip1.animationClip);
+                    AddAnimationEvents(bakerData, animationData, occurences, ref currentEventOccurenceId, ref nbrOfEventOccurenceIds, foundEvents, 
+                        ref currentFoundEventId, dualClipBlendData.clip2.animationClip);
+                }
+                bool loop = animationData.loop;
+                
+                gpuEcsAnimator.animations[animationIndex] = new GpuEcsAnimationData()
+                {
+                    startFrameIndex = currentFrameIndex,
+                    nbrOfFramesPerSample = nbrOfFramesPerSample,
+                    nbrOfInBetweenSamples = nbrOfInBetweenSamples,
+                    blendTimeCorrection = blendTimeCorrection,
+                    startEventOccurenceId = startEventOccurenceId,
+                    nbrOfEventOccurenceIds = nbrOfEventOccurenceIds,
+                    loop = loop,
+                    animationID = animationData.animationID,
+                    stateName = animationData.animatorStateName
+                };
+                currentFrameIndex += nbrOfFramesPerSample * nbrOfInBetweenSamples;
+            }
+            gpuEcsAnimator.totalNbrOfFrames = currentFrameIndex;
+            gpuEcsAnimator.animationEventOccurences = occurences.ToArray();
+            eventNames = bakerData.usePredefinedAnimationEventIds ? bakerData.predefinedAnimationEventIds : foundEvents.ToArray();
+            return gpuEcsAnimator;
+        }
+
+        private static void AddAnimationEvents(GpuEcsAnimationBakerData bakerData, AnimationData animationData, 
+            List<GpuEcsAnimationEventOccurence> occurences, 
+            ref int currentEventOccurenceId, ref int nbrOfEventOccurenceIds, 
+            List<string> foundEvents, ref int currentFoundEventId, AnimationClip animationClip)
+        {
+            AnimationEvent[] animationEvents = AnimationUtility.GetAnimationEvents(animationClip);
+            foreach (AnimationEvent animationEvent in animationEvents)
+            {
+                int eventId = -1;
+                if (bakerData.usePredefinedAnimationEventIds)
+                {
+                    eventId = bakerData.predefinedAnimationEventIds.ToList().FindIndex((n) => n.Equals(animationEvent.stringParameter));
+                    if(eventId == -1) Debug.LogWarning(
+                        $"Found event {animationEvent.stringParameter} that is not in the predefined event Ids list, so it will be ignored.");
+                }
+                else
+                {
+                    string name = $"{animationData.animationID}_{animationEvent.stringParameter}";
+                    eventId = foundEvents.FindIndex((n) => n.Equals(name));
+                    if (eventId == -1)
+                    {
+                        eventId = currentFoundEventId;
+                        foundEvents.Add(name);
+                        currentFoundEventId++;
+                    }
+                }
+
+                if (eventId != -1)
+                {
+                    occurences.Add(new GpuEcsAnimationEventOccurence()
+                    {
+                        eventId = eventId,
+                        eventNormalizedTime = animationEvent.time / animationClip.length,
+                    });
+                    currentEventOccurenceId++;
+                    nbrOfEventOccurenceIds++;
+                }
+            }
+        }
+        
+        private static void ProcessAnimationObjectRecursive(GameObject sourceNode, GameObject targetNode, 
+            Dictionary<GameObject, GameObject> sourceToTargetMapping, string animatorName, string meshPartSuffix,
+            string animationMatricesTexturePartSuffix, string materialPartSuffix,
+            Animator refModelAnimator, LOD[] refModelLoDs, 
+            List<AnimationMatricesTexture> animationMatricesTexturesCache, List<EcsGpuMaterial> ecsGpuMaterialsCache, 
+            GpuEcsAnimationBakerData bakerData, GpuEcsAnimationData[] animations, int totalNbrOfFrames,
+            string generatedAssetsFolder, GpuEcsAnimatorBehaviour gpuEcsAnimator)
+        {
+            sourceToTargetMapping.Add(sourceNode, targetNode);
+            SkinnedMeshRenderer existingSkinnedMeshRenderer = sourceNode.GetComponent<SkinnedMeshRenderer>();
+            if (existingSkinnedMeshRenderer != null)
+            {
+                Texture2D animationMatricesTexture = BakeAndSaveAnimationMatricesTexture(
+                    animationMatricesTexturesCache, generatedAssetsFolder, animatorName, animationMatricesTexturePartSuffix,
+                    refModelAnimator, bakerData, existingSkinnedMeshRenderer, animations, totalNbrOfFrames);
+                Mesh newMesh = BakeAndSaveBoneWeightsIntoMesh(refModelLoDs, generatedAssetsFolder, animatorName,
+                    meshPartSuffix, bakerData, existingSkinnedMeshRenderer);
+
+                MeshFilter meshFilter = targetNode.AddComponent<MeshFilter>();
+                MeshRenderer meshRenderer = targetNode.AddComponent<MeshRenderer>();
+                Material newMaterial = CreateAndSaveEcsGpuMaterial(ecsGpuMaterialsCache, generatedAssetsFolder,
+                    animatorName, materialPartSuffix, existingSkinnedMeshRenderer);
+                newMaterial.SetTexture(AnimatedBoneMatrices, animationMatricesTexture);
+                meshRenderer.sharedMaterial = newMaterial;
+                meshFilter.sharedMesh = newMesh;
+
+                GpuEcsAnimatedMeshBehaviour gpuEcsAnimatedMesh = targetNode.AddComponent<GpuEcsAnimatedMeshBehaviour>();
+                gpuEcsAnimatedMesh.animator = gpuEcsAnimator;
+                gpuEcsAnimatedMesh.transformUsageFlags = bakerData.transformUsageFlagsChildren;
+            }
+
+            for (int childIndex = 0; childIndex < sourceNode.transform.childCount; childIndex++)
+            {
+                GameObject sourceChild = sourceNode.transform.GetChild(childIndex).gameObject;
+                if (sourceChild.gameObject.activeSelf && !CheckEmptyRecursive(sourceChild))
+                {
+                    GameObject targetChild = new GameObject(sourceChild.name);
+                    targetChild.transform.parent = targetNode.transform;
+                    targetChild.transform.localPosition = sourceChild.transform.localPosition;
+                    targetChild.transform.localRotation = sourceChild.transform.localRotation;
+                    targetChild.transform.localScale = sourceChild.transform.localScale;
+                    ProcessAnimationObjectRecursive(sourceChild, targetChild, sourceToTargetMapping,
+                        animatorName, meshPartSuffix, animationMatricesTexturePartSuffix, materialPartSuffix,
+                        refModelAnimator, refModelLoDs, animationMatricesTexturesCache, ecsGpuMaterialsCache,
+                        bakerData, animations, totalNbrOfFrames, generatedAssetsFolder, gpuEcsAnimator);
+                }
+            }
+        }
+
+        private static void RemoveComponent<T>(GameObject gameObject)  where T : Component 
+        {
+            T component = gameObject.GetComponent<T>();
+            if(component != null) Object.DestroyImmediate(component, allowDestroyingAssets:true);
+        }
+        
+        private static bool CheckEmptyRecursive(GameObject node)
+        {
+            Component[] components = node.GetComponents<Component>();
+            bool empty = !components.Any(c => (c is SkinnedMeshRenderer));
+            if (empty)
+            {
+                for (int childIndex = 0; childIndex < node.transform.childCount; childIndex++)
+                {
+                    empty = CheckEmptyRecursive(node.transform.GetChild(childIndex).gameObject);
+                    if (!empty) break;
+                }
+            }
+
+            return empty;
+        }
+        
+        private static Mesh BakeAndSaveBoneWeightsIntoMesh(LOD[] refModelLoDs,
+            string generatedAssetsFolder, string animatorName, string meshPartSuffix, GpuEcsAnimationBakerData bakerData,
+            SkinnedMeshRenderer skinnedMeshRenderer)
+        {
+            int maxNumberOfBonesPerVertex = GetMaxNumberOfBonesPerVertex(refModelLoDs, bakerData, skinnedMeshRenderer);
+            Mesh newMesh = BakeBoneWeightsIntoMesh(skinnedMeshRenderer.sharedMesh, maxNumberOfBonesPerVertex);
+            SavePartAsAsset(newMesh, generatedAssetsFolder, animatorName, skinnedMeshRenderer, meshPartSuffix, "mesh");
+            return newMesh;
+        }
+
+        private static Texture2D BakeAndSaveAnimationMatricesTexture(List<AnimationMatricesTexture> cache,
+            string generatedAssetsFolder, string animatorName, string animationMatricesTexturePartSuffix,
+            Animator refModelAnimator, GpuEcsAnimationBakerData bakerData,
+            SkinnedMeshRenderer skinnedMeshRenderer, GpuEcsAnimationData[] animations, int totalNbrOfFrames)
+        {
+            if (!CheckAnimationMatricesTextureInCache(cache, skinnedMeshRenderer, out Texture2D animationMatricesTexture))
+            {
+                animationMatricesTexture = BakeAnimationMatricesTexture(skinnedMeshRenderer, refModelAnimator, bakerData,
+                    animations, totalNbrOfFrames);
+                SavePartAsAsset(animationMatricesTexture, generatedAssetsFolder, animatorName, skinnedMeshRenderer,
+                    animationMatricesTexturePartSuffix, "asset");
+                    
+                cache.Add(new AnimationMatricesTexture()
+                {
+                    texture = animationMatricesTexture,
+                    skinnedMeshRenderer = skinnedMeshRenderer
+                });
+            }
+            return animationMatricesTexture;
+        }
+
+        private static Material CreateAndSaveEcsGpuMaterial(List<EcsGpuMaterial> cache,
+            string generatedAssetsFolder, string animatorName, string materialPartSuffix,
+            SkinnedMeshRenderer skinnedMeshRenderer)
+        {
+            if (!CheckEcsGpuMaterialInCache(cache, skinnedMeshRenderer, out Material ecsGpuMaterial))
+            {
+                ecsGpuMaterial = Object.Instantiate<Material>(skinnedMeshRenderer.sharedMaterial);
+                ecsGpuMaterial.SetFloat(EnableAnimation, 0);
+                SavePartAsAsset(ecsGpuMaterial, generatedAssetsFolder, animatorName, skinnedMeshRenderer,
+                    materialPartSuffix, "mat");
+                cache.Add(new EcsGpuMaterial()
+                {
+                    material = ecsGpuMaterial,
+                    skinnedMeshRenderer = skinnedMeshRenderer
+                });
+            }
+            return ecsGpuMaterial;
+        }
+
+        private static string GenerateAssetPath(string generatedAssetsFolder, string animatorName,
+            string assetName, string assetFileExtension)
+        {
+            return Path.Combine(generatedAssetsFolder, $"{animatorName}_{assetName}.{assetFileExtension}");
+        }
+        
+        private static void SavePartAsAsset(Object asset, string generatedAssetsFolder, string animatorName,
+            SkinnedMeshRenderer skinnedMeshRenderer, string partName, string assetFileExtension)
+        {
+            string assetName = $"{partName}_{skinnedMeshRenderer.name}";
+            string assetPath = GenerateAssetPath(generatedAssetsFolder, animatorName, assetName, assetFileExtension);
+            AssetDatabase.CreateAsset(asset, assetPath);
+        }
+        
+        private static int GetMaxNumberOfBonesPerVertex(LOD[] refModelLoDs, GpuEcsAnimationBakerData bakerData,
+            SkinnedMeshRenderer skinnedMeshRenderer)
+        {
+            int maxNumberOfBonesPerVertex = bakerData.boneUsage.numberOfBonesPerVertex;
+            if (refModelLoDs != null)
+            {
+                for (int lodIndex = 0; lodIndex < refModelLoDs.Length; lodIndex++)
+                {
+                    if (refModelLoDs[lodIndex].renderers.Any(r => r == (Renderer)skinnedMeshRenderer))
+                    {
+                        BoneUsagePerLoD boneUsagePerLoD = bakerData.boneUsage.boneUsagesPerLoD
+                            .SingleOrDefault(b => b.lodIndex == lodIndex);
+                        if (boneUsagePerLoD != null)
+                            maxNumberOfBonesPerVertex = boneUsagePerLoD.maxNumberOfBonesPerVertex;
+                        break;
+                    }
+                }
+            }
+            return maxNumberOfBonesPerVertex;
+        }
+
+        private static bool CheckAnimationMatricesTextureInCache(List<AnimationMatricesTexture> cache,
+            SkinnedMeshRenderer skinnedMeshRenderer, out Texture2D foundTexture)
+        {
+            bool found = false;
+            foundTexture = null; 
+            foreach (AnimationMatricesTexture cachedTexture in cache)
+            {
+                if (CheckSkinnedMeshRendererHasSameBones(cachedTexture.skinnedMeshRenderer,
+                        skinnedMeshRenderer))
+                {
+                    found = true;
+                    foundTexture = cachedTexture.texture;
+                    break;
+                }
+            }
+            return found;
+        }
+
+        private static bool CheckEcsGpuMaterialInCache(List<EcsGpuMaterial> cache,
+            SkinnedMeshRenderer skinnedMeshRenderer, out Material foundMaterial)
+        {
+            bool found = false;
+            foundMaterial = null;
+            foreach (EcsGpuMaterial cachedEcsGpuMaterial in cache)
+            {
+                if (cachedEcsGpuMaterial.skinnedMeshRenderer.sharedMaterial == skinnedMeshRenderer.sharedMaterial
+                    && CheckSkinnedMeshRendererHasSameBones(cachedEcsGpuMaterial.skinnedMeshRenderer,
+                        skinnedMeshRenderer))
+                {
+                    found = true;
+                    foundMaterial = cachedEcsGpuMaterial.material;
+                    break;
+                }
+            }
+            return found;
+        }
+        
+        private static bool CheckSkinnedMeshRendererHasSameBones(SkinnedMeshRenderer skinnedMeshRendererA,
+            SkinnedMeshRenderer skinnedMeshRendererB)
+        {
+            bool hasSameBones = false;
+            if (skinnedMeshRendererA.bones.Length == skinnedMeshRendererB.bones.Length)
+            {
+                hasSameBones = true;
+                for (int i = 0; i < skinnedMeshRendererA.bones.Length; i++)
+                {
+                    if (!CheckMatrixEquality(skinnedMeshRendererA.bones[i].localToWorldMatrix,
+                            skinnedMeshRendererB.bones[i].localToWorldMatrix))
+                    {
+                        hasSameBones = false; break;
+                    }
+                    if (!CheckMatrixEquality(skinnedMeshRendererA.sharedMesh.bindposes[i],
+                            skinnedMeshRendererB.sharedMesh.bindposes[i]))
+                    {
+                        hasSameBones = false; break;
+                    }
+                }
+            }
+            return hasSameBones;
+        }
+
+        private static bool CheckMatrixEquality(Matrix4x4 m1, Matrix4x4 m2)
+        {
+            return m1.m00 == m2.m00 && m1.m01 == m2.m01 && m1.m02 == m2.m02 && m1.m03 == m2.m03
+                   && m1.m10 == m2.m10 && m1.m11 == m2.m11 && m1.m12 == m2.m12 && m1.m13 == m2.m13
+                   && m1.m20 == m2.m20 && m1.m21 == m2.m21 && m1.m22 == m2.m22 && m1.m23 == m2.m23
+                   && m1.m30 == m2.m30 && m1.m31 == m2.m31 && m1.m32 == m2.m32 && m1.m33 == m2.m33;
+        }
+
+        private static void IterateOverAllFramesThroughAnimator(
+            Animator refModelAnimator, GpuEcsAnimationBakerData bakerData, GpuEcsAnimationData[] animations,
+            System.Action<int> actionPerFrame)
+        {
+            refModelAnimator.speed = 0;
+            int currentFrameIndex = 0;
+
+            for (int animationIndex = 0; animationIndex < bakerData.animations.Length; animationIndex++)
+            {
+                AnimationData animationData = bakerData.animations[animationIndex];
+                GpuEcsAnimationData gpuEcsAnimationData = animations[animationIndex];
+                foreach (AnimatorParameter parameterValue in animationData.additionalAnimatorParameterValues)
+                {
+                    if(parameterValue.parameterType == AnimatorParameterTypes.Bool)
+                        refModelAnimator.SetBool(parameterValue.parameterName, parameterValue.boolValue);
+                    else if(parameterValue.parameterType == AnimatorParameterTypes.Float)
+                        refModelAnimator.SetFloat(parameterValue.parameterName, parameterValue.floatValue);
+                    else if(parameterValue.parameterType == AnimatorParameterTypes.Integer)
+                        refModelAnimator.SetInteger(parameterValue.parameterName, parameterValue.intValue);
+                }
+                
+                for (int sampleIndex = 0; sampleIndex < gpuEcsAnimationData.nbrOfInBetweenSamples; sampleIndex++)
+                {
+                    if (animationData.animationType == AnimationTypes.DualClipBlend)
+                    {
+                        DualClipBlendData dualClipBlendData = animationData.dualClipBlendData;
+                        float sampleRatio = (float)sampleIndex / (float)(gpuEcsAnimationData.nbrOfInBetweenSamples - 1);
+                        float blendValue = dualClipBlendData.clip1.parameterValue +
+                            (dualClipBlendData.clip2.parameterValue - dualClipBlendData.clip1.parameterValue) * sampleRatio;
+                        refModelAnimator.SetFloat(dualClipBlendData.blendParameterName, blendValue);
+                    }
+
+                    for (int frameIndex = 0; frameIndex < gpuEcsAnimationData.nbrOfFramesPerSample; frameIndex++)
+                    {
+                        float progressRatio = (float)frameIndex / (float)(gpuEcsAnimationData.nbrOfFramesPerSample - 1);
+                        refModelAnimator.Play(animationData.animatorStateName, -1, progressRatio);
+                        foreach(AnimatorState animatorState in animationData.additionalAnimatorStatesPerLayer)
+                            refModelAnimator.Play(animatorState.stateName, animatorState.layer, progressRatio);
+                        refModelAnimator.Update(0);
+
+                        actionPerFrame(currentFrameIndex);
+                        
+                        currentFrameIndex++;
+                    }
+                }
+            }
+        }
+
+        private static GpuEcsAttachmentAnchorData BakeAttachmentAnchorTransforms(string generatedAssetsFolder, GameObject sourceModel,
+            string animatorName, Animator refModelAnimator, GpuEcsAnimationBakerData bakerData, GpuEcsAnimationData[] animations,
+            int totalNbrOfFrames)
+        {
+            int nbrOfAttachments = bakerData.attachmentAnchors.Length;
+            if (nbrOfAttachments == 0) return null;
+            else
+            {
+                GpuEcsAttachmentAnchorData gpuEcsAttachmentAnchorData = ScriptableObject.CreateInstance<GpuEcsAttachmentAnchorData>();
+                gpuEcsAttachmentAnchorData.anchorTransforms = new float4x4[totalNbrOfFrames * nbrOfAttachments];
+
+                for (int attachmentAnchorIndex = 0; attachmentAnchorIndex < nbrOfAttachments; attachmentAnchorIndex++)
+                {
+                    AttachmentAnchor attachmentAnchor = bakerData.attachmentAnchors[attachmentAnchorIndex];
+                    Transform referenceAnchorTransform = attachmentAnchor.attachmentAnchorTransform;
+                    Stack<int> siblingIndexStack = new Stack<int>();
+                    GetSiblingIndexStack(referenceAnchorTransform, sourceModel.transform, siblingIndexStack);
+                    Transform anchorTransform = refModelAnimator.transform;
+                    while (siblingIndexStack.Count > 0)
+                        anchorTransform = anchorTransform.GetChild(siblingIndexStack.Pop());
+                    Debug.Assert(anchorTransform.name.Equals(referenceAnchorTransform.name));
+
+                    int baseIndex = attachmentAnchorIndex * totalNbrOfFrames;
+                    IterateOverAllFramesThroughAnimator(refModelAnimator, bakerData, animations,
+                        (currentFrameIndex) =>
+                        {
+                            gpuEcsAttachmentAnchorData.anchorTransforms[baseIndex + currentFrameIndex] = anchorTransform.localToWorldMatrix;
+                        });
+
+                }
+
+                string assetPath = GenerateAssetPath(generatedAssetsFolder, animatorName, "AttachmentAnchors", "asset");
+                AssetDatabase.CreateAsset(gpuEcsAttachmentAnchorData, assetPath);
+                return gpuEcsAttachmentAnchorData;
+            }
+        }
+
+        private static void GetSiblingIndexStack(Transform current, Transform root, Stack<int> currentStack)
+        {
+            if(current.gameObject == root.gameObject) return;
+            currentStack.Push(current.GetSiblingIndex());
+            GetSiblingIndexStack(current.parent, root, currentStack);
+        }
+        
+        private static Texture2D BakeAnimationMatricesTexture(SkinnedMeshRenderer skinnedMeshRenderer, 
+            Animator refModelAnimator, GpuEcsAnimationBakerData bakerData, GpuEcsAnimationData[] animations,
+            int totalNbrOfFrames)
+        {
+            int boneCount = skinnedMeshRenderer.bones.Length;
+            int animationMatricesTextureWidth = boneCount * 3;
+
+            NativeArray<half4> animatedBoneMatricesTextureData = new NativeArray<half4>(
+                totalNbrOfFrames * animationMatricesTextureWidth, Allocator.Temp);
+
+            float4x4 invSkinnedMeshRendererLocalToWorld =  math.inverse(skinnedMeshRenderer.transform.localToWorldMatrix);
+            IterateOverAllFramesThroughAnimator(refModelAnimator, bakerData, animations,
+                (currentFrameIndex) =>
+                {
+                    for (int boneIndex = 0; boneIndex < boneCount; boneIndex++)
+                    {
+                        Transform boneTransform = skinnedMeshRenderer.bones[boneIndex];
+                        if (boneTransform != null)
+                        {
+                            float4x4 matrix = math.mul(
+                                math.mul(invSkinnedMeshRendererLocalToWorld, boneTransform.localToWorldMatrix),
+                                skinnedMeshRenderer.sharedMesh.bindposes[boneIndex]
+                            );
+                            Debug.Assert(Mathf.Approximately(matrix[0][3], 0f)
+                                && Mathf.Approximately(matrix[1][3], 0f)
+                                && Mathf.Approximately(matrix[2][3], 0f)
+                                && Mathf.Approximately(matrix[3][3], 1f), "matrix row 4 must be 0,0,0,1");
+                            int matrixIndex = (currentFrameIndex * animationMatricesTextureWidth) + (boneIndex * 3);
+                            for (int i = 0; i < 3; i++)
+                                animatedBoneMatricesTextureData[matrixIndex + i] = new half4(
+                                    (half)matrix[0][i], (half)matrix[1][i], (half)matrix[2][i], (half)matrix[3][i]);
+                        }
+                    }
+                });
+
+            Texture2D animationMatricesTexture = new Texture2D(animationMatricesTextureWidth, totalNbrOfFrames, 
+                TextureFormat.RGBAHalf, false);
+            animationMatricesTexture.SetPixelData(animatedBoneMatricesTextureData, 0);
+            animationMatricesTexture.Apply();
+
+            animatedBoneMatricesTextureData.Dispose();
+
+            return animationMatricesTexture;
+        }
+        
+        private static Mesh BakeBoneWeightsIntoMesh(Mesh sourceMesh, int maxNumberOfBonesPerVertex)
+        {
+            Mesh mesh = GameObject.Instantiate(sourceMesh);
+            
+            int vertexCount = mesh.vertices.Length;
+            NativeArray<Vector4> uvs1 = new NativeArray<Vector4>(vertexCount, Allocator.Temp);
+            NativeArray<Vector4> uvs2 = new NativeArray<Vector4>(vertexCount, Allocator.Temp);
+            NativeArray<Vector4> uvs3 = new NativeArray<Vector4>(vertexCount, Allocator.Temp);
+            NativeArray<byte> bonesPerVertex = mesh.GetBonesPerVertex();
+            NativeArray<BoneWeight1> boneWeightsSource = mesh.GetAllBoneWeights();
+
+            int startBoneWeightIndex = 0;
+
+            for (int vertIndex = 0; vertIndex < vertexCount; vertIndex++)
+            {
+                float totalWeight = 0f;
+                float totalWeightCapped = 0f;
+                int numberOfBonesForThisVertex = bonesPerVertex[vertIndex];
+
+                int boneWeightIndexTemp = startBoneWeightIndex;
+                for (int i = 0; i < numberOfBonesForThisVertex; i++)
+                {
+                    BoneWeight1 currentBoneWeight = boneWeightsSource[boneWeightIndexTemp];
+                    totalWeight += currentBoneWeight.weight;
+                    if (i < maxNumberOfBonesPerVertex) totalWeightCapped += currentBoneWeight.weight;
+                    if (i > 0) Debug.Assert(boneWeightsSource[boneWeightIndexTemp - 1].weight >= currentBoneWeight.weight);
+                    boneWeightIndexTemp++;
+                }
+                Debug.Assert(Mathf.Approximately(1f, totalWeight));
+
+                float weightMultiplier = totalWeight / totalWeightCapped;
+                int nbrOfBonesToBake = math.min(maxNumberOfBonesPerVertex, numberOfBonesForThisVertex);
+
+                totalWeight = 0f;
+                boneWeightIndexTemp = startBoneWeightIndex;
+                float4 uv1 = float4.zero;
+                float4 uv2 = float4.zero;
+                float4 uv3 = float4.zero;
+                for (int i = 0; i < nbrOfBonesToBake; i++)
+                {
+                    BoneWeight1 currentBoneWeight = boneWeightsSource[boneWeightIndexTemp];
+                    float adjustedWeight = currentBoneWeight.weight * weightMultiplier; 
+                    totalWeight += adjustedWeight;
+                    boneWeightIndexTemp++;
+                    if      (i == 0) uv1 = new float4(currentBoneWeight.boneIndex, adjustedWeight, uv1.z, uv1.w);
+                    else if (i == 1) uv1 = new float4(uv1.x, uv1. y, currentBoneWeight.boneIndex, adjustedWeight);
+                    else if (i == 2) uv2 = new float4(currentBoneWeight.boneIndex, adjustedWeight, uv2.z, uv2.w);
+                    else if (i == 3) uv2 = new float4(uv2.x, uv2. y, currentBoneWeight.boneIndex, adjustedWeight);
+                    else if (i == 4) uv3 = new float4(currentBoneWeight.boneIndex, adjustedWeight, uv3.z, uv3.w);
+                    else if (i == 5) uv3 = new float4(uv3.x, uv3. y, currentBoneWeight.boneIndex, adjustedWeight);
+                }
+                Debug.Assert(Mathf.Approximately(1f, totalWeight));
+                uvs1[vertIndex] = uv1;
+                uvs2[vertIndex] = uv2;
+                uvs3[vertIndex] = uv3;
+                startBoneWeightIndex += numberOfBonesForThisVertex;
+            }
+            
+            mesh.SetUVs(1, uvs1);
+            mesh.SetUVs(2, uvs2);
+            mesh.SetUVs(3, uvs3);
+            
+            uvs1.Dispose();
+            uvs2.Dispose();
+            uvs3.Dispose();
+            bonesPerVertex.Dispose();
+            boneWeightsSource.Dispose();
+            return mesh;
+        }
+    }
+}
+#endif

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakeServices.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 63f784a8ff004921b1d2dccaf617a1b3
+timeCreated: 1678439503

+ 31 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerBehaviour.cs

@@ -0,0 +1,31 @@
+using System;
+using GpuEcsAnimationBaker.Engine.Data;
+using Unity.Entities;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.Baker
+{
+    [DisallowMultipleComponent]
+    [RequireComponent(typeof(Animator))]
+    public class GpuEcsAnimationBakerBehaviour : MonoBehaviour
+    {
+        public GpuEcsAnimationBakerData bakerData = new GpuEcsAnimationBakerData()
+        {
+            animations = Array.Empty<AnimationData>(),
+            generateAnimationIdsEnum = false,
+            animationIdsEnumName = "",
+            attachmentAnchors = Array.Empty<AttachmentAnchor>(),
+            generateAttachmentAnchorIdsEnum = false,
+            attachmentAnchorIdsEnumName = "",
+            boneUsage = new BoneUsage()
+            {
+                numberOfBonesPerVertex = 6,
+                boneUsagesPerLoD = Array.Empty<BoneUsagePerLoD>()
+            },
+            transformUsageFlagsParent = TransformUsageFlags.Dynamic,
+            transformUsageFlagsChildren = TransformUsageFlags.Renderable
+        };
+        [Tooltip("The last generated GPU ECS animator. This is used so that existing references will not be lost after regeneration")]
+        public GameObject gpuEcsAnimator;
+    }
+}

+ 11 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerBehaviour.cs.meta

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

+ 79 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerEditor.cs

@@ -0,0 +1,79 @@
+#if UNITY_EDITOR
+using System.IO;
+using GpuEcsAnimationBaker.Engine.Data;
+using UnityEditor;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.Baker
+{
+    [CustomEditor(typeof(GpuEcsAnimationBakerBehaviour))]
+    public class GpuEcsAnimationBakerEditor : UnityEditor.Editor
+    {
+        private SerializedProperty bakerDataProperty;
+        private SerializedProperty gpuEcsAnimatorProperty;
+        private bool showPrefabError = false;
+        
+        void OnEnable()
+        {
+            bakerDataProperty = serializedObject.FindProperty("bakerData");
+            gpuEcsAnimatorProperty = serializedObject.FindProperty("gpuEcsAnimator");
+            showPrefabError = false;
+        }
+
+        public override void OnInspectorGUI()
+        {
+            GameObject sourceModel = ((GpuEcsAnimationBakerBehaviour)target).gameObject;
+            GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
+            labelStyle.normal.textColor = new Color(1f, 0.5f, 0f, 1f);
+            labelStyle.wordWrap = true; 
+            labelStyle.alignment = TextAnchor.MiddleLeft;
+            labelStyle.fontSize = 22;
+            labelStyle.fontStyle = FontStyle.Bold;
+            labelStyle.fixedHeight = 36;
+            GUILayout.Label("GPU ECS Animation Baker", labelStyle);
+            serializedObject.Update();
+            EditorGUILayout.PropertyField(bakerDataProperty);
+
+            bool validated = GpuEcsAnimationBakerServices.ValidateAnimationBakerData(
+                (GpuEcsAnimationBakerData)bakerDataProperty.boxedValue, sourceModel, out string errors);
+            if(!validated) EditorGUILayout.HelpBox(errors, MessageType.Error);
+            if(showPrefabError) EditorGUILayout.HelpBox("Generation can only happen on unloaded, selected prefabs", MessageType.Error);
+            GUI.enabled = validated;
+            GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
+            buttonStyle.normal.textColor = new Color(1f, 0.5f, 0f, 1f);
+            buttonStyle.alignment = TextAnchor.MiddleCenter;
+            buttonStyle.fontSize = 22;
+            buttonStyle.fontStyle = FontStyle.Bold;
+            buttonStyle.fixedHeight = 36;
+            if (GUILayout.Button("Generate GPU ECS Animator", buttonStyle))
+            {
+                string path = AssetDatabase.GetAssetPath(sourceModel);
+                if (string.IsNullOrEmpty(path) || !PrefabUtility.IsPartOfAnyPrefab(sourceModel))
+                    showPrefabError = true;
+                else
+                {
+                    string folder = Path.GetDirectoryName(path);
+                    string subFolder = $"BakedAssets_{sourceModel.name}";
+                    string generatedAssetsFolder = Path.Combine(folder, subFolder);
+                    if (!AssetDatabase.IsValidFolder(generatedAssetsFolder))
+                        generatedAssetsFolder = AssetDatabase.GUIDToAssetPath(AssetDatabase.CreateFolder(
+                            folder, subFolder));
+                    string animatorName = sourceModel.name;
+
+                    GpuEcsAnimationBakerData bakerData = (GpuEcsAnimationBakerData)bakerDataProperty.boxedValue;
+                    GameObject newGpuEcsAnimator = GpuEcsAnimationBakerServices.GenerateAnimationObject(path, bakerData,
+                        animatorName, generatedAssetsFolder);
+                    
+                    gpuEcsAnimatorProperty.boxedValue = newGpuEcsAnimator;
+                    showPrefabError = false;
+                }
+            }
+            GUI.enabled = true;
+
+            EditorGUILayout.PropertyField(gpuEcsAnimatorProperty);
+            
+            serializedObject.ApplyModifiedProperties();
+        }
+    }
+}
+#endif

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerEditor.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 79d531cf89b84b1da8f743add3d8f9e0
+timeCreated: 1678439969

+ 22 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerMenu.cs

@@ -0,0 +1,22 @@
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.Baker
+{
+    public static class GpuEcsAnimationBakerMenu
+    {
+        [MenuItem("Tools/GPU ECS Animation Baker/Add baker component")]
+        private static void AddGpuEcsAnimationBaker()
+        {
+            Selection.activeGameObject.AddComponent<GpuEcsAnimationBakerBehaviour>();
+        }    
+        
+        [MenuItem("Tools/GPU ECS Animation Baker/Add baker component", isValidateFunction:true)]
+        private static bool ValidateAddGpuEcsAnimationBaker()
+        {
+            return Selection.activeGameObject != null && Selection.activeGameObject.GetComponent<Animator>() != null;
+        }
+    }
+}
+#endif

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationBakerMenu.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 9a5d3f31af424f1abf047c581f9c9618
+timeCreated: 1679327604

+ 12 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationEventBakerBehaviour.cs

@@ -0,0 +1,12 @@
+using UnityEngine;
+
+namespace GPUECSAnimationBaker.Engine.Baker
+{
+    public class GpuEcsAnimationEventBakerBehaviour : MonoBehaviour
+    {
+        public void RaiseEvent(string eventID)
+        {
+            //Debug.Log($"RaiseEvent{eventID}");
+        }
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Baker/GpuEcsAnimationEventBakerBehaviour.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: b5f0e3091ef64b7dbbd1aeeb69aa23fc
+timeCreated: 1692112016

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 173879fcf9ec40b59acfdd918e36a942
+timeCreated: 1678696737

+ 25 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimationData.cs

@@ -0,0 +1,25 @@
+using System;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [Serializable]
+    public struct AnimationData
+    {
+        [Tooltip("Only used when generating enum code file to identify animations")]
+        public string animationID;
+        [Tooltip("The main animator state name that will be used during sampling, searched across all layers")]
+        public string animatorStateName;
+        [Tooltip("Specify single clip or dual clip blend animations")]
+        public AnimationTypes animationType;
+        public SingleClipData singleClipData;
+        public DualClipBlendData dualClipBlendData;
+        [Tooltip("Specify whether the animation should loop")]
+        public bool loop;
+        [Tooltip("Any additional Animator parameters that will be used during sampling (independent of blending)\nSpecify name, type & value for each")]
+        public AnimatorParameter[] additionalAnimatorParameterValues;
+        [Tooltip("Any additional Animator states that need to be set on different layers")]
+        public AnimatorState[] additionalAnimatorStatesPerLayer;
+    }
+
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimationData.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 6b1068b7fce641d8a7bc80e6bebcbbe7
+timeCreated: 1678696820

+ 94 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimationDataDrawer.cs

@@ -0,0 +1,94 @@
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [CustomPropertyDrawer(typeof(AnimationData))]
+    public class AnimationDataDrawer : PropertyDrawer
+    {
+        private Rect GetLineRect(Rect position, int line, float indent)
+        {
+            return new Rect(position.x + indent, position.y + line * EditorGUIUtility.singleLineHeight,
+                position.width - indent, EditorGUIUtility.singleLineHeight);
+        }
+        
+        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+        {
+            EditorGUI.BeginProperty(position, label, property);
+            SerializedProperty animationIDProperty = property.FindPropertyRelative("animationID");
+            SerializedProperty animatorStateNameProperty = property.FindPropertyRelative("animatorStateName");
+            SerializedProperty animationTypeProperty = property.FindPropertyRelative("animationType");
+            SerializedProperty singleClipDataProperty = property.FindPropertyRelative("singleClipData");
+            SerializedProperty dualClipBlendDataProperty = property.FindPropertyRelative("dualClipBlendData");
+            SerializedProperty loopDataProperty = property.FindPropertyRelative("loop");
+            SerializedProperty additionalParameterValuesProperty = property.FindPropertyRelative("additionalAnimatorParameterValues");
+            SerializedProperty additionalAnimatorStatesPerLayerProperty = property.FindPropertyRelative("additionalAnimatorStatesPerLayer");
+            int line = 0;
+            EditorGUI.PropertyField(GetLineRect(position, line, 0), animationIDProperty, new GUIContent("Animation ID"));
+            line++;
+            EditorGUI.PropertyField(GetLineRect(position, line, 0), animatorStateNameProperty, new GUIContent("Animator State Name"));
+            line++;
+            EditorGUI.PropertyField(GetLineRect(position, line, 0), animationTypeProperty, new GUIContent("Animation Type"));
+            AnimationTypes animationType = (AnimationTypes)animationTypeProperty.enumValueIndex;
+            if (animationType == AnimationTypes.SingleClip)
+            {
+                line++;
+                EditorGUI.PropertyField(GetLineRect(position, line, 0), 
+                    singleClipDataProperty.FindPropertyRelative("animationClip"), new GUIContent("Animation Clip"));
+            }
+            else
+            {
+                line++;
+                EditorGUI.PropertyField(GetLineRect(position, line, 0), 
+                    dualClipBlendDataProperty.FindPropertyRelative("blendParameterName"), new GUIContent("Blend parameter name"));
+                line++;
+                EditorGUI.LabelField(GetLineRect(position, line, 0), "Clip 1"); 
+                line++;
+                EditorGUI.PropertyField(GetLineRect(position, line, 10), 
+                    dualClipBlendDataProperty.FindPropertyRelative("clip1").FindPropertyRelative("parameterValue"), new GUIContent("Parameter Value"));
+                line++;
+                EditorGUI.PropertyField(GetLineRect(position, line, 10), 
+                    dualClipBlendDataProperty.FindPropertyRelative("clip1").FindPropertyRelative("animationClip"), new GUIContent("Animation Clip"));
+                line++;
+                EditorGUI.LabelField(GetLineRect(position, line, 0), "Clip 2"); 
+                line++;
+                EditorGUI.PropertyField(GetLineRect(position, line, 10), 
+                    dualClipBlendDataProperty.FindPropertyRelative("clip2").FindPropertyRelative("parameterValue"), new GUIContent("Parameter Value"));
+                line++;
+                EditorGUI.PropertyField(GetLineRect(position, line, 10), 
+                    dualClipBlendDataProperty.FindPropertyRelative("clip2").FindPropertyRelative("animationClip"), new GUIContent("Animation Clip"));
+                line++;
+                EditorGUI.PropertyField(GetLineRect(position, line, 0), 
+                    dualClipBlendDataProperty.FindPropertyRelative("nbrOfInBetweenSamples"), new GUIContent("Nbr of in between samples"));
+            }
+            line++;
+            EditorGUI.PropertyField(GetLineRect(position, line, 0), 
+                loopDataProperty, new GUIContent("Loop"));
+            line++;
+            EditorGUI.PropertyField(GetLineRect(position, line, 0), 
+                additionalParameterValuesProperty, new GUIContent("Additional animator parameter values"));
+            line++;
+            if (additionalParameterValuesProperty.isExpanded)
+                line += additionalParameterValuesProperty.arraySize + 3;
+            EditorGUI.PropertyField(GetLineRect(position, line, 0), 
+                additionalAnimatorStatesPerLayerProperty, new GUIContent("Additional animator states per layer"));
+            EditorGUI.EndProperty();
+        }
+
+        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+        {
+            SerializedProperty animationTypeProperty = property.FindPropertyRelative("animationType");
+            SerializedProperty additionalParameterValuesProperty = property.FindPropertyRelative("additionalAnimatorParameterValues");
+            SerializedProperty additionalAnimatorStatesPerLayerProperty = property.FindPropertyRelative("additionalAnimatorStatesPerLayer");
+            AnimationTypes animationType = (AnimationTypes)animationTypeProperty.enumValueIndex;
+            int nbrOfLines = animationType == AnimationTypes.SingleClip ? 7 : 14;
+            if (additionalParameterValuesProperty.isExpanded)
+                nbrOfLines += additionalParameterValuesProperty.arraySize + 3;
+            if (additionalAnimatorStatesPerLayerProperty.isExpanded)
+                nbrOfLines += additionalAnimatorStatesPerLayerProperty.arraySize + 3;
+            return EditorGUIUtility.singleLineHeight * nbrOfLines;
+        }
+    }
+}
+#endif

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimationDataDrawer.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: ce81459ba0ea4380b87cfb510a462a27
+timeCreated: 1679232760

+ 10 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimationMatricesTexture.cs

@@ -0,0 +1,10 @@
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    public class AnimationMatricesTexture
+    {
+        public SkinnedMeshRenderer skinnedMeshRenderer;
+        public Texture2D texture;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimationMatricesTexture.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 42de9783325447ef91539ab4a3ea8cf2
+timeCreated: 1678701051

+ 8 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimationTypes.cs

@@ -0,0 +1,8 @@
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    public enum AnimationTypes
+    {
+        SingleClip,
+        DualClipBlend
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimationTypes.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 412ca53240eb4635a973d73941e241e2
+timeCreated: 1679220803

+ 15 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameter.cs

@@ -0,0 +1,15 @@
+using System;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [Serializable]
+    public struct AnimatorParameter
+    {
+        public string parameterName;
+        public AnimatorParameterTypes parameterType;
+        public bool boolValue;
+        public float floatValue;
+        public int intValue;
+    }
+
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameter.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: ddd84665f7c4491bb9163b12b133b111
+timeCreated: 1678696899

+ 41 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameterDrawer.cs

@@ -0,0 +1,41 @@
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [CustomPropertyDrawer(typeof(AnimatorParameter))]
+    public class AnimatorParameterDrawer : PropertyDrawer
+    {
+        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+        {
+            EditorGUI.BeginProperty(position, label, property);
+            float w = (position.width - 90) / 2;
+            SerializedProperty parameterNameProperty = property.FindPropertyRelative("parameterName");
+            SerializedProperty parameterTypeProperty = property.FindPropertyRelative("parameterType");
+            SerializedProperty boolValueProperty = property.FindPropertyRelative("boolValue");
+            SerializedProperty floatValueProperty = property.FindPropertyRelative("floatValue");
+            SerializedProperty intValueProperty = property.FindPropertyRelative("intValue");
+            EditorGUI.PropertyField(new Rect(position.position, new Vector2(w, position.height)), 
+                parameterNameProperty, new GUIContent(""));
+            EditorGUI.BeginChangeCheck();            
+            EditorGUI.PropertyField(new Rect(position.position + new Vector2(w + 5, 0), new Vector2(80, position.height)), 
+                parameterTypeProperty, new GUIContent(""));
+            if (EditorGUI.EndChangeCheck())
+            {
+                boolValueProperty.boolValue = false;
+                floatValueProperty.floatValue = 0;
+                intValueProperty.intValue = 0;
+            }
+            AnimatorParameterTypes parameterType = (AnimatorParameterTypes)parameterTypeProperty.enumValueIndex;
+            SerializedProperty valueProperty = null;
+            if (parameterType == AnimatorParameterTypes.Bool) valueProperty = boolValueProperty;
+            else if (parameterType == AnimatorParameterTypes.Float) valueProperty = floatValueProperty;
+            else if (parameterType == AnimatorParameterTypes.Integer) valueProperty = intValueProperty;
+            EditorGUI.PropertyField(new Rect(position.position + new Vector2(w + 90, 0), new Vector2(w, position.height)), 
+                valueProperty, new GUIContent(""));
+            EditorGUI.EndProperty();
+        }
+    }
+}
+#endif

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameterDrawer.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 368626b264a74b1bb9090157b32f8ebd
+timeCreated: 1678696928

+ 9 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameterTypes.cs

@@ -0,0 +1,9 @@
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    public enum AnimatorParameterTypes
+    {
+        Bool,
+        Float,
+        Integer
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorParameterTypes.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 39fde7d787f34da48e67b42a25cf6bd3
+timeCreated: 1678696872

+ 11 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorState.cs

@@ -0,0 +1,11 @@
+using System;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [Serializable]
+    public struct AnimatorState
+    {
+        public string stateName;
+        public int layer;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorState.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 9323c2b3448d40239301108a1256de89
+timeCreated: 1683552170

+ 31 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorStateDrawer.cs

@@ -0,0 +1,31 @@
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [CustomPropertyDrawer(typeof(AnimatorState))]
+    public class AnimatorStateDrawer : PropertyDrawer
+    {
+        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+        {
+            EditorGUI.BeginProperty(position, label, property);
+            SerializedProperty parameterStateNameProperty = property.FindPropertyRelative("stateName");
+            SerializedProperty parameterLayerProperty = property.FindPropertyRelative("layer");
+            EditorGUI.LabelField(new Rect(position.position, 
+                    new Vector2(80, position.height)),
+                "Layer"); 
+            EditorGUI.PropertyField(new Rect(position.position + new Vector2(85f, 0f), 
+                    new Vector2(80, position.height)), 
+                parameterLayerProperty, new GUIContent(""));
+            EditorGUI.LabelField(new Rect(position.position + new Vector2(170, 0f), 
+                    new Vector2(80, position.height)),
+                "State Name"); 
+            EditorGUI.PropertyField(new Rect(position.position + new Vector2(255f, 0f), 
+                    new Vector2(position.width - 255, position.height)), 
+                parameterStateNameProperty, new GUIContent(""));
+            EditorGUI.EndProperty();
+        }
+    }
+}
+#endif

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AnimatorStateDrawer.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 59192f8c669e456dbb74bc1160f6fa9e
+timeCreated: 1683618281

+ 14 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AttachmentAnchor.cs

@@ -0,0 +1,14 @@
+using System;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [Serializable]
+    public struct AttachmentAnchor
+    {
+        [Tooltip("Only used when generating attachments code file to identify anchors")]
+        public string attachmentAnchorID;
+        [Tooltip("Reference to the attachment transform inside the bone hierarchy")]
+        public Transform attachmentAnchorTransform;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AttachmentAnchor.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: a9bc78f1bbb04dabbb9a514f404acf63
+timeCreated: 1691932719

+ 29 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AttachmentAnchorDrawer.cs

@@ -0,0 +1,29 @@
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [CustomPropertyDrawer(typeof(AttachmentAnchor))]
+    public class AttachmentAnchorDrawer : PropertyDrawer
+    {
+        private Rect GetLineRect(Rect position, int line, float indent)
+        {
+            return new Rect(position.x + indent, position.y + line * EditorGUIUtility.singleLineHeight,
+                position.width - indent, EditorGUIUtility.singleLineHeight);
+        }
+        
+        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+        {
+            EditorGUI.BeginProperty(position, label, property);
+            SerializedProperty attachmentAnchorIDProperty = property.FindPropertyRelative("attachmentAnchorID");
+            SerializedProperty attachmentAnchorTransformProperty = property.FindPropertyRelative("attachmentAnchorTransform");
+            int line = 0;
+            EditorGUI.PropertyField(GetLineRect(position, line, 0), attachmentAnchorIDProperty, new GUIContent("Anchor ID"));
+            line++;
+            EditorGUI.PropertyField(GetLineRect(position, line, 0), attachmentAnchorTransformProperty, new GUIContent("Anchor Transform reference"));
+            EditorGUI.EndProperty();
+        }
+    }
+}
+#endif

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/AttachmentAnchorDrawer.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: c1b6041a50014cb58b464f3afe81e4bd
+timeCreated: 1691933300

+ 13 - 0
Assets/GPUECSAnimationBaker/Engine/Data/BoneUsage.cs

@@ -0,0 +1,13 @@
+using System;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [Serializable]
+    public struct BoneUsage
+    {
+        [Tooltip("The default max number of bones to take into account for baking (unless specified per LoD underneath)")]
+        public int numberOfBonesPerVertex;
+        public BoneUsagePerLoD[] boneUsagesPerLoD;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/BoneUsage.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 3601768870634e3c8e0672b1248c5a8c
+timeCreated: 1678696786

+ 14 - 0
Assets/GPUECSAnimationBaker/Engine/Data/BoneUsagePerLoD.cs

@@ -0,0 +1,14 @@
+using System;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [Serializable]
+    public class BoneUsagePerLoD
+    {
+        [Tooltip("The LOD index this number applies to")]
+        public int lodIndex;
+        [Tooltip("The max number of bones to take into account for baking for this LOD")]
+        public int maxNumberOfBonesPerVertex;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/BoneUsagePerLoD.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 501b94ca64794edaac85dde931fd9f93
+timeCreated: 1678698143

+ 25 - 0
Assets/GPUECSAnimationBaker/Engine/Data/BoneUsagePerLoDDrawer.cs

@@ -0,0 +1,25 @@
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [CustomPropertyDrawer(typeof(BoneUsagePerLoD))]
+    public class BoneUsagePerLoDDrawer: PropertyDrawer
+    {
+        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+        {
+            EditorGUI.BeginProperty(position, label, property);
+            SerializedProperty lodIndexProperty = property.FindPropertyRelative("lodIndex");
+            SerializedProperty maxNumberOfBonesPerVertexProperty = property.FindPropertyRelative("maxNumberOfBonesPerVertex");
+            EditorGUI.LabelField(new Rect(position.position, new Vector2(30, position.height)), "LOD");
+            EditorGUI.PropertyField(new Rect(position.position + new Vector2(35, 0), new Vector2(30, position.height)), 
+                lodIndexProperty, new GUIContent(""));
+            EditorGUI.LabelField(new Rect(position.position + new Vector2(70, 0), new Vector2(80, position.height)), "Nbr. of bones");
+            EditorGUI.PropertyField(new Rect(position.position + new Vector2(155, 0), new Vector2(position.width - 160, position.height)), 
+                maxNumberOfBonesPerVertexProperty, new GUIContent(""));
+            EditorGUI.EndProperty();
+        }
+    }
+}
+#endif

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/BoneUsagePerLoDDrawer.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 44d8a087aa8441c69b370845581dc44d
+timeCreated: 1678697020

+ 26 - 0
Assets/GPUECSAnimationBaker/Engine/Data/DualClipBlendData.cs

@@ -0,0 +1,26 @@
+using System;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [Serializable]
+    public struct DualClipBlendData
+    {
+        [Tooltip("The animator parameter that will be used to blend")]
+        public string blendParameterName;
+        public DualClipBlendAnimationClip clip1;
+        public DualClipBlendAnimationClip clip2;
+        
+        [Tooltip("The nbr of samples to take. More will result in better results but larger baked animation textures")]
+        public int nbrOfInBetweenSamples;
+    }
+                    
+    [Serializable]
+    public struct DualClipBlendAnimationClip
+    {
+        [Tooltip("The animator parameter value to blend from or to")]
+        public float parameterValue;
+        [Tooltip("Only used to determine the length of the animation.")]
+        public AnimationClip animationClip;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/DualClipBlendData.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 9fdf4cc0cb65414786cc2fb6a30e64f2
+timeCreated: 1679220750

+ 10 - 0
Assets/GPUECSAnimationBaker/Engine/Data/EcsGpuMaterial.cs

@@ -0,0 +1,10 @@
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    public class EcsGpuMaterial
+    {
+        public SkinnedMeshRenderer skinnedMeshRenderer;
+        public Material material;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/EcsGpuMaterial.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: e8d1d69f52e84137b4d225c127f1671a
+timeCreated: 1678796827

+ 7 - 0
Assets/GPUECSAnimationBaker/Engine/Data/GlobalConstants.cs

@@ -0,0 +1,7 @@
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    public class GlobalConstants
+    {
+        public const float SampleFrameRate = 30f;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/GlobalConstants.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: a2cd2f5b0ffc499dbd92ccb129d9c949
+timeCreated: 1679222579

+ 38 - 0
Assets/GPUECSAnimationBaker/Engine/Data/GpuEcsAnimationBakerData.cs

@@ -0,0 +1,38 @@
+using System;
+using Unity.Entities;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [Serializable]
+    public struct GpuEcsAnimationBakerData
+    {
+        public AnimationData[] animations;
+        [Tooltip("Specifies if an animation Ids enum code file needs to be generated")]
+        public bool generateAnimationIdsEnum;
+        [Tooltip("Specifies the name of the animation Ids enum to be generated")]
+        public string animationIdsEnumName;
+        
+        [Tooltip("Specifies if a predefined event IDs list should be used when searching for events")]
+        public bool usePredefinedAnimationEventIds;
+        [Tooltip("Predefined event IDs list used when searching for events")]
+        public string[] predefinedAnimationEventIds;
+        [Tooltip("Specifies if an animation event Ids enum code file needs to be generated")]
+        public bool generateAnimationEventIdsEnum;
+        [Tooltip("Specifies the name of the animation event Ids enum to be generated")]
+        public string animationEventIdsEnumName;
+        
+        public AttachmentAnchor[] attachmentAnchors;
+        [Tooltip("Specifies if an attachment anchor Ids enum code file needs to be generated")]
+        public bool generateAttachmentAnchorIdsEnum;
+        [Tooltip("Specifies the name of the attachment anchor Ids enum to be generated")]
+        public string attachmentAnchorIdsEnumName;
+        
+        public BoneUsage boneUsage;
+        [Tooltip("Specifies the TransformUsageFlags to be used when converting the parent animator to an ECS entity")]
+        
+        public TransformUsageFlags transformUsageFlagsParent;
+        [Tooltip("Specifies the TransformUsageFlags to be used when converting the child meshes to an ECS entity")]
+        public TransformUsageFlags transformUsageFlagsChildren;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/GpuEcsAnimationBakerData.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 5f63c8e07aa34ce9b4e023d0b1b15428
+timeCreated: 1678443247

+ 55 - 0
Assets/GPUECSAnimationBaker/Engine/Data/GpuEcsAnimationBakerDataDrawer.cs

@@ -0,0 +1,55 @@
+#if UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [CustomPropertyDrawer(typeof(GpuEcsAnimationBakerData))]
+    public class GpuEcsAnimationBakerDataDrawer : PropertyDrawer
+    {
+        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
+        {
+            EditorGUI.BeginProperty(position, label, property);
+            SerializedProperty animationsProperty = property.FindPropertyRelative("animations");
+            SerializedProperty generateAnimationIdsEnumProperty = property.FindPropertyRelative("generateAnimationIdsEnum");
+            SerializedProperty animationIdsEnumNameProperty = property.FindPropertyRelative("animationIdsEnumName");
+
+            SerializedProperty usePredefinedAnimationEventIdsProperty = property.FindPropertyRelative("usePredefinedAnimationEventIds");
+            SerializedProperty predefinedAnimationEventIdsProperty = property.FindPropertyRelative("predefinedAnimationEventIds");
+            SerializedProperty generateAnimationEventIdsEnumProperty = property.FindPropertyRelative("generateAnimationEventIdsEnum");
+            SerializedProperty animationEventIdsEnumNameProperty = property.FindPropertyRelative("animationEventIdsEnumName");
+            
+            SerializedProperty attachmentAnchorsProperty = property.FindPropertyRelative("attachmentAnchors");
+            SerializedProperty generateAttachmentAnchorIdsEnumProperty = property.FindPropertyRelative("generateAttachmentAnchorIdsEnum");
+            SerializedProperty attachmentAnchorIdsEnumNameProperty = property.FindPropertyRelative("attachmentAnchorIdsEnumName");
+            
+            SerializedProperty boneUsageProperty = property.FindPropertyRelative("boneUsage");
+            
+            SerializedProperty transformUsageFlagsParentProperty = property.FindPropertyRelative("transformUsageFlagsParent");
+            SerializedProperty transformUsageFlagsChildrenProperty = property.FindPropertyRelative("transformUsageFlagsChildren");
+
+            EditorGUILayout.PropertyField(animationsProperty);
+            EditorGUILayout.PropertyField(generateAnimationIdsEnumProperty);
+            if(generateAnimationIdsEnumProperty.boolValue)
+                EditorGUILayout.PropertyField(animationIdsEnumNameProperty);
+            
+            EditorGUILayout.PropertyField(usePredefinedAnimationEventIdsProperty);
+            if(usePredefinedAnimationEventIdsProperty.boolValue)
+                EditorGUILayout.PropertyField(predefinedAnimationEventIdsProperty);
+            EditorGUILayout.PropertyField(generateAnimationEventIdsEnumProperty);
+            if(generateAnimationEventIdsEnumProperty.boolValue)
+                EditorGUILayout.PropertyField(animationEventIdsEnumNameProperty);
+            
+            EditorGUILayout.PropertyField(attachmentAnchorsProperty);
+            EditorGUILayout.PropertyField(generateAttachmentAnchorIdsEnumProperty);
+            if(generateAttachmentAnchorIdsEnumProperty.boolValue)
+                EditorGUILayout.PropertyField(attachmentAnchorIdsEnumNameProperty);
+            
+            EditorGUILayout.PropertyField(boneUsageProperty);
+            
+            EditorGUILayout.PropertyField(transformUsageFlagsParentProperty);
+            EditorGUILayout.PropertyField(transformUsageFlagsChildrenProperty);
+        }
+    }
+}
+#endif

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/GpuEcsAnimationBakerDataDrawer.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 3723fac0ebc94dc1b44e2fa379fd5b09
+timeCreated: 1679402718

+ 12 - 0
Assets/GPUECSAnimationBaker/Engine/Data/SingleClipData.cs

@@ -0,0 +1,12 @@
+using System;
+using UnityEngine;
+
+namespace GpuEcsAnimationBaker.Engine.Data
+{
+    [Serializable]
+    public struct SingleClipData
+    {
+        [Tooltip("Only used to determine the length of the animation")]
+        public AnimationClip animationClip;
+    }
+}

+ 3 - 0
Assets/GPUECSAnimationBaker/Engine/Data/SingleClipData.cs.meta

@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 66644fbbf51c4d23b3cf33cbf7f747e3
+timeCreated: 1679220712

部分文件因文件數量過多而無法顯示