Search Unity

Mesh Animator - Highly efficient animated crowds. For support, please use email.

Discussion in 'Assets and Asset Store' started by jschieck, Dec 7, 2014.

  1. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Thanks for the heads up! I'll get in touch with Unity support to get it fixed.

    1.5.5 has minor optimizations and fixes for the Nintendo Switch.
     
    wood333 likes this.
  2. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    I'll test on that version and see what the issue is. Is it giving you errors?
     
  3. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    To get smoother animations you need to increase the bake FPS. So if you're running your application at 60 FPS, and want it to update every frame, you need to bake at 60.

    With a simple mesh like that, you will start to see better performance gains with greater numbers (like 5k-10k and beyond) . 1000 meshes isn't that many when comparing the two methodologies.
     
  4. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Well yes you'll have smoother animations with the default animator component because it's animating bones along animation curves. Think of mesh animator like a flip book of animation frames that are being swapped.

    Even older Android devices should be able to handle 1000 without much issue especially the mesh is as simple as you said. Your bottleneck will more likely be rendering.
     
  5. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Hey everyone! I've put together another short demo video showing the performance gain from using Mesh Animator and plan to make a short tutorial video to go with it soon. Enjoy!

     
    AthrunVLokiz and ftejada like this.
  6. blackbird

    blackbird

    Joined:
    Aug 9, 2011
    Posts:
    592
    what is included in the package
     
  7. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    It includes the source code (obviously), and several examples for performance comparison testing. Full documentation can be found here.
     
    blackbird likes this.
  8. blackbird

    blackbird

    Joined:
    Aug 9, 2011
    Posts:
    592
    the zombie example is no where to be found , which the main reason why i bought it
     
  9. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Yes I am still working on building a suitable example to include in the asset.
     
  10. blackbird

    blackbird

    Joined:
    Aug 9, 2011
    Posts:
    592
    i see , i thought it was included , how long will take you to deliver it ?
     
  11. witcher101

    witcher101

    Joined:
    Sep 9, 2015
    Posts:
    516
    Does this work with webgl??
     
  12. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Yes, though no multi-threading support for crossfading as webgl doesn't support threads.
     
  13. Mateusz_Wenkly

    Mateusz_Wenkly

    Joined:
    Sep 18, 2018
    Posts:
    1
    Hello. I just noticed that when you use frame skip and expose transform, the transforms which you expose do not move as smooth as the animation. Is there any workaround for this?
     
  14. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    I will need to make a fix for this and will PM you the update.

    EDIT: @Mateusz_Wenkly PM'd you a fix. Everyone else this is fixed in version 1.5.8 which is currently under review.
     
    Last edited: Dec 20, 2018
  15. blackbird

    blackbird

    Joined:
    Aug 9, 2011
    Posts:
    592
    still no zombie example ? if you don't plan to release it , could you refund me please
     
  16. Archie747

    Archie747

    Joined:
    Jan 7, 2015
    Posts:
    25
    Hi, Im interested in this mesh animator asset
    I want to implement this in my android & ios RTS game,
    so, can it work on mobile if I have around 30 different characters?
    or how many maximum different characters will work with this asset?

    thanks
     
    Last edited: Dec 23, 2018
  17. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    The more characters you have, the greater amount of memory is required. If they are very simple meshes, and have only 1 or 2 animations, it might be okay. The system stores each frame of animation as a separate mesh, so memory requirements can grow quite rapidly. You can estimate how much you would need by putting one of your characters in an empty scene, then open the profiler in the memory section, switch to Detailed, and take a snapshot. Examine how much memory is required for your mesh.

    upload_2018-12-28_12-25-48.png

    So in this case 0.5MB is used by 2 references, so about 290KB per frame of animation for that mesh when baked when Mesh Animator.
    upload_2018-12-28_12-27-13.png
    (each frame of animation takes up 290 KB of memory)

    So in your case it would be something like: number of animation total frames * 30 characters * memory requirement for each mesh. That should give you a rough estimate of what would be required to use this system.
     

    Attached Files:

  18. Archie747

    Archie747

    Joined:
    Jan 7, 2015
    Posts:
    25
    Great thanks!..
    forgot to ask, what is the requirement for mobile, does the asset will works with OpenGLES 2.0?
    or what is the minimum requirement for mobile, thank you..
     
  19. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    There are no special requirements as far as Graphics API, unless you are attempting to use GPU instancing. MeshAnimator itself doesn't use any custom shaders or materials.
     
  20. HenryChinaski

    HenryChinaski

    Joined:
    Jul 9, 2013
    Posts:
    108
    I hope this question was not answered before (I looked through the thread).
    I use MeshAnimator in a project due to the aesthetics provided by small compression accuracy.
    I noticed, that if I use the Mecanim + MeshAnimator component, there is no blending / fading between the single animations for idle, walk etc. I saw the "Crossfade" bool on the component, but it doesn't seem to do anything.
    What am I missing? Is this expected behavior?
     
  21. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    The default blend time when calling the Crossfade method blend time is only 0.1 seconds, it's possible that if you're using the MecanimMeshAnimatorController, it uses that. You might want to try editing that script and pass in your own desired crossfade duration so that it can be observed better.
     
    JBR-games likes this.
  22. HenryChinaski

    HenryChinaski

    Joined:
    Jul 9, 2013
    Posts:
    108
    That totally fixed it. Thanks!
     
    JBR-games likes this.
  23. Ardinius

    Ardinius

    Joined:
    Oct 4, 2015
    Posts:
    57
    I haven't played with Mesh Animator in a while so please forgive me, just comming back to it.
    Is there anyway to override how shadows are handled?
    As I still want the Units to receive and cast shadows when near the camera, but with so many Units my framerate tanks with the Quality settings of shadows set to Ultra, its ok with Very High but then the rest of the scene suffers.
    I was wondering if there was a way to over ride shadow settings for Mesh Animator objects so they have their own distance?

    Or if not is their a hook in for LOD, so if model in a certain LOD it changes shadow casting to off?

    Or another method perhaps?

    great asset.
     
  24. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    What you could do using Unity's built in LOD system, use the same mesh animator prefab at each level, but on the ones further away just turn of shadows on those MeshRenderer's. That will accomplish what you're trying to do.
     
    JBR-games likes this.
  25. Black_Raptor

    Black_Raptor

    Joined:
    Nov 3, 2014
    Posts:
    181
    Hi !

    I would like to know before purchase this asset if he's compatible with unity 2018.3+.
    You said :
    "• Can be controlled using Mecanim, no need to re-write existing code or controllers, just attach a script."
    So it's work with any animator ? Blendtree is supported ?
     
  26. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Hey,

    Yes, 2018.3+ is supported. Blendtree's are not supported as the animations are prebaked and cannot be blended together.
    The mecanim controller script will take the active state and try and play it on the newly baked prefab, but since mecanim isn't really needed, it's probably best to write your own controller to avoid the unnecessary overhead and get better performance.
     
  27. Black_Raptor

    Black_Raptor

    Joined:
    Nov 3, 2014
    Posts:
    181
    And the zombie example is still not included ?
     
  28. HenryChinaski

    HenryChinaski

    Joined:
    Jul 9, 2013
    Posts:
    108
    Hey,

    unfortunately, I have another problem.
    I use the MecanimMeshAnimatorController component and changed the crossfade time to a reasonable amount if you want to blend between idle, walking etc.
    Now, in the exact frames where the crossfading takes place, the material of the model becomes darker and overall noticeably changes in a way. I am not really sure, but I believe it has something to do with the normals recalculating. I already checked the "instant normals calculation" checkbox of the respective animations, but it did not change anything.
    Has it maybe something to do with me using a compression accuracy of 20?
    Or am I missing something else?
     
  29. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    I cannot include the zombie demo in my asset because it uses a paid versions of several other assets. The zombie controller itself isn't anything special, it just uses Unity's navigation system and some simple logic. Here's the controller for it:
    Code (CSharp):
    1. using FSG.MeshAnimator;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.AI;
    6.  
    7. public class ZombieController : MonoBehaviour
    8. {
    9.     private static WaitForSeconds s_tick;
    10.     private static WaitForSeconds s_attackTick;
    11.     private static WaitForSeconds s_deathTick;
    12.     private static Vector3 s_playerPosition;
    13.     private static bool s_isFirst = false;
    14.     [RuntimeInitializeOnLoadMethod]
    15.     private static void Init()
    16.     {
    17.         Application.targetFrameRate = 60;
    18.         s_tick = new WaitForSeconds(0.25f);
    19.         s_attackTick = new WaitForSeconds(2f);
    20.         s_deathTick = new WaitForSeconds(5f);
    21.     }
    22.  
    23.     private enum State
    24.     {
    25.         Idle,
    26.         Dead,
    27.         Wandering,
    28.         TargetPursue,
    29.         Attack,
    30.         Hit
    31.     }
    32.     [SerializeField]
    33.     private float m_agroDistance = 5f;
    34.     [SerializeField]
    35.     private float m_crawlDistance = 5f;
    36.     [SerializeField]
    37.     private float m_attackRange = 0.5f;
    38.     [SerializeField]
    39.     private float m_walkSpeed = 0.5f;
    40.     [SerializeField]
    41.     private float m_runSpeed = 5f;
    42.     [SerializeField]
    43.     private int m_health = 5;
    44.     [SerializeField]
    45.     private GameObject m_animatorPrefab;
    46.     [SerializeField]
    47.     private GameObject m_impact;
    48.  
    49.     private NavMeshAgent m_agent;
    50.     private State m_state;
    51.     private MeshAnimator m_animator;
    52.     private int m_currentHealth;
    53.     private float m_agroSqr;
    54.     private float m_crawlSqr;
    55.     private float m_attackSqr;
    56.  
    57.     protected virtual void Awake()
    58.     {
    59.         m_agent = GetComponent<NavMeshAgent>();
    60.         m_agent.avoidancePriority = Random.Range(-1000, 1000);
    61.         m_agent.obstacleAvoidanceType = ObstacleAvoidanceType.NoObstacleAvoidance;
    62.         m_agroSqr = m_agroDistance * m_agroDistance;
    63.         m_crawlSqr = m_crawlDistance * m_crawlDistance;
    64.         m_attackSqr = m_attackSqr * m_attackSqr;
    65.         if (!s_isFirst)
    66.         {
    67.             s_isFirst = true;
    68.             Recycler.Pool(m_animatorPrefab, 1000);
    69.             FindObjectOfType<ZombieSpawner>().StartCoroutine(UpdateStatics());
    70.         }
    71.     }
    72.     private void OnEnable()
    73.     {
    74.         Recycler.Instantiate(m_animatorPrefab, transform.position, transform.rotation, transform);
    75.         m_animator = GetComponentInChildren<MeshAnimator>();
    76.         if (m_animator != null)
    77.         {
    78.             m_animator.PrepopulateCrossfadePool(1000);
    79.         }
    80.         m_currentHealth = m_health;
    81.         StartCoroutine(Tick());
    82.     }
    83.     private IEnumerator UpdateStatics()
    84.     {
    85.         Transform player = GameObject.FindGameObjectWithTag("Player").transform;
    86.         var tick = new WaitForSeconds(0.1f);
    87.         while (player != null)
    88.         {
    89.             s_playerPosition = player.position;
    90.             yield return tick;
    91.         }
    92.     }
    93.     private IEnumerator Tick()
    94.     {
    95.         m_state = State.Idle;
    96.         var m_collider = GetComponent<Collider>();
    97.         m_agent.obstacleAvoidanceType = ObstacleAvoidanceType.NoObstacleAvoidance;
    98.         while (enabled)
    99.         {
    100.             yield return s_tick;
    101.             m_collider.enabled = m_state != State.Dead;
    102.             switch (m_state)
    103.             {
    104.                 case State.Idle:
    105.                     {
    106.                         while (Random.value > 0.25f && m_state == State.Idle)
    107.                         {
    108.                             StopAgent();
    109.                             PlayAnimation("idle");
    110.                             yield return s_tick;
    111.                         }
    112.                         m_agent.enabled = true;
    113.                         Vector3 pos = transform.position + new Vector3(Random.Range(-20f, 20f), 0, Random.Range(-20f, 20f));
    114.                         NavMeshHit hit;
    115.                         NavMesh.SamplePosition(pos, out hit, 1000, -1);
    116.                         m_agent.SetDestination(hit.position);
    117.                         m_state = State.Wandering;
    118.                         break;
    119.                     }
    120.                 case State.Wandering:
    121.                     {
    122.                         m_agent.speed = m_walkSpeed;
    123.                         while (m_agent.hasPath && m_state == State.Wandering)
    124.                         {
    125.                             if (m_agent.velocity.magnitude < 0.1f)
    126.                             {
    127.                                 PlayAnimation("idle");
    128.                             }
    129.                             else
    130.                             {
    131.                                 PlayAnimation("walk");
    132.                             }
    133.                             if (DistanceToPlayer() < m_agroSqr)
    134.                             {
    135.                                 m_agent.SetDestination(s_playerPosition);
    136.                                 m_state = State.TargetPursue;
    137.                                 break;
    138.                             }
    139.                             yield return s_tick;
    140.                         }
    141.                         if (m_state == State.Wandering)
    142.                             m_state = State.Idle;
    143.                         break;
    144.                     }
    145.                 case State.TargetPursue:
    146.                     {
    147.                         m_agent.speed = m_runSpeed;
    148.                         bool crawlOrRun = Random.value > 0.5f;
    149.                         string anim = crawlOrRun ? "crawl" : "run";
    150.                         m_agent.obstacleAvoidanceType = ObstacleAvoidanceType.LowQualityObstacleAvoidance;
    151.                         while (m_agent.hasPath && m_state == State.TargetPursue)
    152.                         {
    153.                             float distanceToPlayer = DistanceToPlayer();
    154.                             if (distanceToPlayer > m_agroSqr + 4)
    155.                             {
    156.                                 m_state = State.Idle;
    157.                                 break;
    158.                             }
    159.                             PlayAnimation(anim, 0.1f);
    160.                             m_agent.SetDestination(s_playerPosition);
    161.                             if (distanceToPlayer < m_attackSqr)
    162.                             {
    163.                                 m_state = State.Attack;
    164.                                 break;
    165.                             }
    166.                             yield return s_tick;
    167.                         }
    168.                         if (m_state == State.TargetPursue)
    169.                             m_state = State.Idle;
    170.                         m_agent.obstacleAvoidanceType = ObstacleAvoidanceType.NoObstacleAvoidance;
    171.                         break;
    172.                     }
    173.                 case State.Attack:
    174.                     {
    175.                         StopAgent();
    176.                         PlayAnimation("attack");
    177.                         transform.LookAt(s_playerPosition);
    178.                         yield return s_attackTick;
    179.                         m_state = State.Idle;
    180.                         break;
    181.                     }
    182.                 case State.Dead:
    183.                     {
    184.                         yield return s_deathTick;
    185.                         Cleanup();
    186.                         break;
    187.                     }
    188.                 case State.Hit:
    189.                     {
    190.                         StopAgent();
    191.                         yield return s_tick;
    192.                         m_agent.enabled = true;
    193.                         m_agent.SetDestination(s_playerPosition);
    194.                         m_state = State.TargetPursue;
    195.                         break;
    196.                     }
    197.             }
    198.         }
    199.     }
    200.     private float DistanceToPlayer()
    201.     {
    202.         Vector3 pos = transform.position;
    203.         if (s_playerPosition.y - pos.y > 5)
    204.             return float.MaxValue;
    205.         return (transform.position - s_playerPosition).sqrMagnitude;
    206.     }
    207.     private void Damage(Vector3 point)
    208.     {
    209.         m_currentHealth--;
    210.         if (m_currentHealth <= 0)
    211.         {
    212.             StopAgent();
    213.             GetComponent<Collider>().enabled = false;
    214.             m_state = State.Dead;
    215.             string anim = Random.value > 0.5f ? "death1" : "death2";
    216.             PlayAnimation(anim);
    217.         }
    218.         else
    219.         {
    220.             StopAgent();
    221.             transform.LookAt(s_playerPosition);
    222.             m_state = State.Hit;
    223.             PlayAnimation("hit");
    224.         }
    225.         Recycler.Instantiate(m_impact, point);
    226.     }
    227.     private void StopAgent()
    228.     {
    229.         if (m_agent.enabled)
    230.         {
    231.             m_agent.isStopped = true;
    232.             m_agent.enabled = false;
    233.         }
    234.     }
    235.     protected virtual void Cleanup()
    236.     {
    237.         if (m_animator != null)
    238.             Recycler.Recycle(m_animator.gameObject);
    239.         Recycler.Recycle(gameObject);
    240.     }
    241.     protected virtual void PlayAnimation(string animation)
    242.     {
    243.         m_animator.Crossfade(animation, 0.15f);
    244.     }
    245. }
     
  30. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Yes it is most likely a normal calculation issue. On the MeshAnimator component itself, have you tried turning off recalculateCrossfadeNormals?
     
  31. HenryChinaski

    HenryChinaski

    Joined:
    Jul 9, 2013
    Posts:
    108
    That did the trick! Didn't know about this option!
    Thanks!
     
  32. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    Hello- great asset- works well and its easy to use :)

    I read the docs but still have some questions-

    Let's say I have a model I'm using with 800 verts- if I'm using MeshAnimator with an accuracy of 0.1- will that use up less memory than the full 800 vert model would? Or is the memory usage based on the base model that we use to generate the animations?

    Let's say my animation is 8 seconds long- but I skip every 3 frames and run it at 15fps- Is it going to use less memory than the full 8 second clip?

    The reason I ask is because the doc's state "The best use of Mesh Animator is with low-poly models with short animations"

    So would a long clip that is optimized using frame skipping and lowering the frame rate be considered a "short animation"?

    If I have a model I plan to instantiate several times but each with a different idle animation- what would be more performant- to use one mesh animator model with several animations on it? or a separate mesh animator model- each one with one animation on it?

    Thank you.
     
    Last edited: Jun 29, 2019
  33. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Runtime memory is determined by your original mesh, so however much memory that takes, is how much each frame will take.

    Frame skip and compression accuracy only effect the size of the baked files.

    So if you want to use less memory, reduce vertex counts or if you can shorten animations as much as possible.

    Using a single mesh animator with multiple animations will be slightly more performant, but have no real effect on memory usage.
     
  34. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    Thank you for the quick answers.
     
  35. p_hergott

    p_hergott

    Joined:
    May 7, 2018
    Posts:
    414
    Just real quick. Using synty models. Explosives rpg animations. For making a army of ... x things. Like goblins for example. That have scripts and colliders. Having, 10 animations each. Would this work? And be easy to set up?
     
  36. Carterryan1990

    Carterryan1990

    Joined:
    Dec 29, 2016
    Posts:
    79
    I did so by simply looking into the unity docs! All of the scripts are there already smh
     
  37. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Sorry you feel this way. But there's 100s of satisfied customers that have used my tool in production games and projects. I'd be happy to issue you a refund.
     
  38. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Yes it should work well with those models. The tool simply replaces the animator and the skinned mesh renderer so all of you colliders and scripts will continue to work.
     
  39. Carterryan1990

    Carterryan1990

    Joined:
    Dec 29, 2016
    Posts:
    79
    You know what that was rude of me I’m sorry. But I still believe there are far easier and more efficient solutions as stated I was able to do so and have 1 million characters with 200 FPS... When I used your system which I was never able to use it in release because the quality was just not there I wasnt able to notice a big difference between unitys and yours.. Anyways good luck no refund needed. If you like I can share how I did mine and maybe you can rebuild yours on it...
     
    Last edited: Aug 6, 2019
  40. p_hergott

    p_hergott

    Joined:
    May 7, 2018
    Posts:
    414
    Well i played with it for a few minutes. Just using defaults. I was able to run 500 characters running around the screen. So thats pretty cool.
     
  41. p_hergott

    p_hergott

    Joined:
    May 7, 2018
    Posts:
    414
    Thats cool and all. But most assets dont help ppl achieve the impossible or anything, they typically help simplify, and reduce production times. I personally wouldnt know where to start on replicating this, could i learn, sure. Like a model, i could spend a month in blender making a character, but id rather spend a few bucks and just get one. Like dont get me wrong 74k characters, is pretty sweet.
     
  42. GermiyanBey

    GermiyanBey

    Joined:
    Aug 18, 2017
    Posts:
    68
    Hi jschieck! I don't know if this is asked before, but this is important for me in my consideration of purchasing,

    I have characters that share same mesh but multiple different materials (Different armor, clothing on same mesh) and I procedurally instantiate them so they all look different when spawned from toe to hair. (gloves, hair, beard, face, armor, boots... are all seperate skinned meshes)

    Does Mesh Animator grant support for such uses? Can I use Mesh Animator effectively with my setup? Thanks.
    (I read the documentation already, I had some worries such as this after)
     
  43. Ignacii

    Ignacii

    Joined:
    May 23, 2013
    Posts:
    108
    Edit: Next-Gen Soft-Shadows 2 asset caused the problem.

    Hi jschieck!

    Updated to Unity 2019.2.3 to fix one important problem but I encountered this problem with MeshAnimator:


    Looks like Z-fighting. Happens only with MeshAnimator objects. Can't wait for a fix!
     
    Last edited: Sep 1, 2019
  44. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    If it's truly the same mesh, and you're simply swapping materials, then it will work. But if you enabling/disabling different parts then it will probably not work well. You could do some tricks with making parts of the mesh invisible with vertex colors but probably not worth the trouble for such a setup.
     
    GermiyanBey likes this.
  45. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Can you PM me your model and I'll take a closer look?
     
  46. GermiyanBey

    GermiyanBey

    Joined:
    Aug 18, 2017
    Posts:
    68
    I had skinned meshes below a parent object like:
    -Hair1
    -Hair2
    -Hair3
    -Beard1
    ..
    -Beard9
    -ChestArmor
    -Helmet1
    ...
    -Helmet10

    I removed Skinned Mesh Renderers of "Hair", "Beard" and "Helmet" meshes (the parts not really animated) and added the Mesh Filters and Mesh Renderers, then put them as children of the relevant rig objects. (In this approach, only Chest, Arm and Leg parts will have their own Skinned Mesh Renderers, 3 parts in total. I believe they will be merged by Mesh Animator in Animation? I will swap their materials as you mentioned, yes)

    Now can I expect Mesh Animator work smoothly with various Mesh Filters (I click Add Mesh Filter on Mesh Animator window) in this fashion?

    Yes in this approach, I plan to enable/disable these different Mesh Filters (Hair1...9, Helmet 1...10, Beard 1....9, Sword 1...4, etc.) at spawning the object and then the animation will start play. Is this setup good for Mesh Animator? This way, no Skinned Mesh will be enabled/disabled but Mesh Filters? (Fingers crossed)
     
    Last edited: Aug 30, 2019
  47. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Yes in this case the 3 skinned meshes would be merged. Then expose the transforms you wish to parent objects to (head, hand bones, etc...) In the bake window and parent the static meshes to the mesh animator child transforms when you instantiate them.
     
    GermiyanBey likes this.
  48. eron82

    eron82

    Joined:
    Mar 10, 2017
    Posts:
    83
    Hi, do you think you could gain more performance using the new Unity ECS/DOTS system?
     
  49. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    Yes if built from the ground up using ECS/DOTS you could probably get better performance. I did at one point have plans to do that with Mesh Animator but the areas that cause the most CPU slowdown wouldn't benefit much from it. Mesh swapping is the biggest slowdown which wouldn't be made faster by using DOTS. Crossfading could be moved to such a system though, but it's also already multi-threaded and so not much to be gained there. Drawing meshes with GPU shaders creates the biggest performance gains, and building a better system to use textures for animations would be the way to go, but that requires too much granularity to be usable by the masses in the asset store.
     
    Ignacii likes this.
  50. GermiyanBey

    GermiyanBey

    Joined:
    Aug 18, 2017
    Posts:
    68
    I had PMed you and waiting an answer for two days so I can continue working on my project after your assistance. I am writing here to ping you, I hope everything is good there.