Search Unity

[RELEASED] GPU Instancer - Crowd Animations

Discussion in 'Assets and Asset Store' started by LouskRad, Apr 29, 2019.

  1. ummonk

    ummonk

    Joined:
    Jun 28, 2020
    Posts:
    2
    This might have an obvious answer, but a couple questions.

    First, in the no-game-object workflow, is there a way to obtain an animation clip by name or tag, rather than needing to know its index in animationData.clipDataList?

    Second, how do I "un-bake" animation clips? After updating my animation controller (by both adding and deleting clips), I've found that deleted clips are still baked.
     
  2. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    There are two versions of the StartAnimation/StartBlend methods, so you can either use the original AnimationClip or the GPUIAnimationClipData.

    Please update to Version 1.1.3:
     
    ummonk likes this.
  3. OmnifariousStudios

    OmnifariousStudios

    Joined:
    Mar 12, 2018
    Posts:
    48
    Hello!
    Loving both of these assets. It’s insane how much you can do with them!

    Wanted to ask your thoughts on using Crowd Animations and ragdolls.

    Essentially I want to make a pedestrian system for my city using CA, but activate a basic ragdoll when close enough, or just on contact with a pedestrian instance. Or if need be, switch out an instance with a ragdoll prefab? Not sure which is the best way to go.

    Also, would the Culling Group API be usable to turn on/off scripts on the instances based on distance, or should I stick with the trigger activation like in the asteroid demo?

    Thanks!!
     
  4. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    I am glad you like the assets.

    You will not be able to use Culling Group API with GPUI, since GPUI uses its own culling and LOD system. I think it would be best to check distances or collisions yourself and use the GPUI API to remove instances and replace them with ragdolls.
     
  5. OmnifariousStudios

    OmnifariousStudios

    Joined:
    Mar 12, 2018
    Posts:
    48

    Good to know, thank you!

    Follow up question: is there a way to use GPUInstancer for destruction effects? Let’s say I wanted to destroy a building, could I instance debris pieces or quads to make it look like thousands of broken pieces?
     
  6. CitrioN

    CitrioN

    Joined:
    Oct 6, 2016
    Posts:
    100
    Hello,

    I got a few questions:

    The first ones are regarding the 'Has Optional Renderers' setting.
    Could this be used to enable/disable different kinds of clothing to get a bunch of character variants?
    If so how does this impact performance?

    Since the asset doesn't have IK support I would like to know if it would be possible to use an LOD like system to switch between the default Unity implementation and the asset?

    Thanks,
    CitrioN
     
  7. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    If you are reusing the same mesh/material combination for the broken pieces, then yes. If you have unique meshes, then no.

    Hi there,
    Yes you can use the 'Has Optional Renderers' setting for clothing variation. Every skinned mesh will generate it's own draw call, so it will have an affect on performance when you have many different meshes. If there are cases where you only make material property changes, it is better to use Material Variations.

    You can use the GPUI API to add/remove instances based on distance.
     
    CitrioN likes this.
  8. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    There are occasions where I call
    UnityEngine.Object.Destroy(gameObject);
    and get the following error:

    upload_2022-7-20_14-32-6.png

    Looks like GPUI is trying to remove the prefab instance but cant find the index? I am using automatically add/remove instances flag.
     
  9. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    I am not sure why you are getting this error. Might be related to execution order or some methods might incorrectly being executed multiple times.
    I suggest disabling the auto. add/remove and using the AddPrefabInstance/RemovePrefabInstance API methods instead. Then you can make sure to, add the instance after instantiate, and remove it before destroy, and call it only once.
    Or if you can create a sample repro project, email it to us and we can investigate.
     
    mrCharli3 likes this.
  10. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    Perhaps you could wrap the statement in a try/catch in your end as well, to avoid it.
     
  11. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    The fact that all children are flattened out causes a lot of issues for me. Is there some sort of event or something I can listen to so that I can re-parent them after the flattening of the heirarchy happens? Not being able to use the inspector heirarchy is a big limitation on the asset.
     
    Last edited: Jul 25, 2022
  12. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    Any advice on best way to sequence animations? I am trying to play animation X when animation Y finishes, so I add an event to the last frame on animation Y that plays animation X, but it triggers very very randomly, only works about 20% of the time.

    All my other events like sounds and vfx trigger fine, so I know I'm doing it the right way.
     
  13. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    No. This is not a preference, it is a requirement. We have to flatten the hierarchies so they can be used in suitable data structures on the GPU and can be processed in threads.

    Yes, it looks like there might be cases when an animation is not looping, the event at the last frame might not be triggered.
    Try removing this if condition at line 336-337 in GPUICrowdAnimator.cs and see if it solves the issue:
    Code (CSharp):
    1. if (clipData.IsLoopDisabled() && clipTotalTime > clipData.length)
    2.     continue;
     
  14. ummonk

    ummonk

    Joined:
    Jun 28, 2020
    Posts:
    2
    What's the equivalent of this for cutting out calls to StartAnimation? It's the one thing I haven't been able to convert over to the Jobs System in my code currently.
     
  15. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    You need to edit the runtimeData.animationData and runtimeData.crowdAnimatorControllerData to modify active animations. See the BlendAnimations method inside GPUICrowdAnimator.cs to see how it is used.
     
    ummonk likes this.
  16. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    How can I make sure my prefabs are initialized and registered? I though that is what
    AddPrefabInstance
    did? Reading the docs it feels like I am missing some step but I am not sure which.

    The extra weird thing is that the issue only occurs on startup. If I let the game start and then Instantiate my prefabs it works fine. So I think something is not being sequenced correctly.

    Could it have something to do with which scene it is? I use the Crowd manager in several scenes. I did not turn the Manager into a prefab since I saw you did not recommend that, instead I manually add each prefab to the manager, in each scene. Seems to run fine in one scene but not the other.

    upload_2022-7-26_11-59-55.png
    upload_2022-7-26_11-54-17.png
    upload_2022-7-26_11-54-43.png

    EDIT:
    Even though nothing was changed, I remove the Crowd manager component from my scene, added a new one, and re-added the prefabs to the manager (these prefabs were already setup for GPUI so nothing new was generated when added); This fixed my issue. Feels a bit buggy tbh.
     

    Attached Files:

    Last edited: Jul 27, 2022
  17. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Please make sure that you do not have multiple Crowd Managers across different scenes, and only have one manager with DontDestroyOnLoad for the manager's gameObject on the initial scene.
     
    mrCharli3 likes this.
  18. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi everyone,

    I just wanted to let you know that the GPU Instancer team will be on a summer break until September 1st. We will be answering all the questions and support requests after the break.
     
  19. OmnifariousStudios

    OmnifariousStudios

    Joined:
    Mar 12, 2018
    Posts:
    48
    Hello again!

    Was wondering if it's possible to get the animation clip and animation time when de-instancing a crowd prefab?

    When my player gets close to an instance, or the instance collides with something, I remove it using the API and replace with a regular prefab (with a ragdoll). But the prefab would need to match the last position of the animated instance, or it makes the transition really obvious. Any advice on how I might do this?


    Thanks!
     
  20. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    You can use the GetAnimationTime API method for the time, but there is not a method for retrieving the current clip. So you will need to keep track of the animations you started.
     
  21. exitsimulation

    exitsimulation

    Joined:
    Feb 10, 2014
    Posts:
    82
    Hello! I am experiencing this weird bug after baking the animations for my rigged model with GPUI Crowd Instancer. In Unity itself the animation is being represented correctly, then after baking with the plug-in it stretches certain polygons like this across the whole model. We thought it was due to errors in the weight painting on certain vertices but no matter what we try the bug persists. Any ideas on your end? Thank you


    upload_2022-9-9_18-27-46.png
     
  22. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    If you have multiple skinned meshes with different bind pose values for the same bones, it might be the source of the issue. It is a known issue that we are looking for a solution. But in any case if you can email us a sample project where we can see the issue, we can investigate.
     
  23. exitsimulation

    exitsimulation

    Joined:
    Feb 10, 2014
    Posts:
    82
    Thanks for getting back to me on this. We found the solution, it was a faulty export issue that was hard to pin down.
     
  24. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Hi, I've been working an an AI system using CrowdAnimator (for... omg over a year) and lately I implemented conversion between crowd animated entities and active ragdolls and its 99% perfect except in very rare occasions where I suspect the crowd animator is in a blend, which causes the characters switching to a ragdoll to "jerk" as its not in the exact right pose to match the crowd animation.

    So I got 3 questions:
    1- How can I detect if the Crowd Animator is currently in a blend?
    2- How do I get how far along the "blend" is? (like the current blend time)
    3- How can I restore the state of a blend? Ie.: Source animation, destination animation and the current blend time

    If we can figure this out I will have something pretty cool to show you guys :)

    Bonus question: As per your experience, is there anything else I should investigate regarding this "rare" animation position mismatch?

    Thank you very much!
     
    Last edited: Sep 22, 2022
  25. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    crowdPrefab.crowdAnimator.activeClipCount > 1

    Crowd Animator does not have states, so there is no blend time instead every clip has its own time while blending:
    crowdPrefab.GetAnimationTime(animationClip1)
    crowdPrefab.GetAnimationTime(animationClip2)

    You can set any state using StartAnimation or StartBlend methods with the correct parameters:

    I can not say much without seeing it. If you can email us a sample, we can have a look.
     
    tcz8 likes this.
  26. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Thank you for the reply.

    Concerning the blend time, I'm a little confused on how to translate that into a mecanim "transition time" equivalence.

    Do you have a suggestion?
     
  27. CitrioN

    CitrioN

    Joined:
    Oct 6, 2016
    Posts:
    100
    Hello,
    If I have 2 models using the exact same bone and transform structure, can I technically swap out the prefab reference in the GPUI Crowd Prototype without breaking things? The reasoning for this would be to bake the data once and allow the prefab for the visuals be injected at runtime before actually adding it to the manager. Would that be possible?
     
  28. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Transition data is stored separately, you can access the time it started from:
    crowdPrefab.crowdAnimator.transition.startTime
    and you can check if the animator is in transition using:
    crowdPrefab.crowdAnimator.isInTransition

    Hi there,
    You can use the DefineGameObjectAsCrowdPrototypeAtRuntime API method to add prototypes at runtime with the animation data parameter (GPUICrowdAnimationData animationData).
     
    tcz8 and CitrioN like this.
  29. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    So, I've been trying to make this work, but I still can't figure out how to restore in the middle of a transition. StartAnimation and StartBlend have a transitionTime, but I feel this is the wrong term. TransitionTime in unity's API appears to be the time since the current transition started, not the TransitionDuration?

    If you look at the docs for CrossFade you can specify the animationTime (aka offset), the transitionDuration and a NormalizedTransitionTime parameter. Unfortunatly unity is short on details on what that parameter is, but it seems like it would set the time position or how far along we are on a transition duration.

    With StartBlend I can specify the animationTime for each clip and the duration of the transition, but how do I set the position to resume the transition from? (like 0.25 seconds into the transition instead of starting it at 0 seconds)

    EDIT: After investigating your code further, looks like what may work is to set Transition.startTime in the past? An overload to StartAnimation and StarBlend with an extra transitionTime parameter that gets substracted from starTime would be a welcome addition.

    Extra question: How does StartBlend knows which animation is the target of the transition when you can specify 4 clips? I mean, which clip will keep playing after the transition is over.? Does it have anything to do with animation Weights?

    Thank you for your support.
     
    Last edited: Oct 3, 2022
  30. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Here is the description of the transitionTime parameter:
    For example, if your character is playing the animation "A" and you call StartAnimation method for the animation "B" with the transitionTime parameter 2 seconds. Then the animator will blend animation A and B, starting with weights 1 and 0 respectively, and ending with 0 and 1 within 2 seconds where the character will be playing only the animation B at the end. The weights will go like this:
    0 seconds: A = 1, B = 0
    0.5 seconds: A = 0.75, B = 0.25
    1.0 seconds: A = 0.5, B = 0.5
    1.5 seconds: A = 0.25, B = 0.75
    2.0 seconds: A = 0, B = 1

    So if I wanted to start this same transition at the 0.5 seconds, first I need to set the weights to that state. So I would first call:
    Code (CSharp):
    1. StartBlend(crowdInstance, new Vector4(0.25f, 0.75f, 0, 0), animationA, animationB, null, null, new Vector4(0.5f, 0.5f, 0, 0))
    Note: You can use the animationTimes parameter here to specify when exactly each animation is started. I assumed they both were playing for 0.5 seconds.

    Now I want to end with only playing animation B within 1.5 seconds, so I will call:
    Code (CSharp):
    1. StartAnimation(crowdInstance, animationClipB, -1.0f, 1.0f, 1.5f)
    I hope this helps clear things up.
     
    Last edited: Oct 6, 2022
    tcz8 likes this.
  31. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    It makes total sense, thank you so much for the explanation! I was expecting crowd animator to be the hard part, but after testing this it's actually mecanim that doesn't want to play ball :rolleyes:

    Hopefully Unity's support will be as helpful :confused:
     
  32. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    If this is not a typo, I don't understand why the weight gets switched around like that. Could you elaborate?
     
    Last edited: Oct 5, 2022
  33. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    It is a typo. I corrected it. Thanks for pointing out.
     
    tcz8 likes this.
  34. animal531

    animal531

    Joined:
    Aug 26, 2014
    Posts:
    25
    I'm getting a strange issue in GPUInstancerUtility.cs, every now and then when I launch I'll get an exception on this line:
    instanceVisibilityComputeKernelId = cameraComputeKernelIDs[!isInitial && runtimeData.prototype.isLODCrossFade ? 1 : 0];

    Debugging it I can see that cameraComputeKernelIDs is null. If I pause the project and resume everything seems to be ok from then on.
     
  35. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    This issue was caused by a change in Unity's editor behavior in recent versions and it was solved in GPUI v1.7.4. Please update to the latest GPU Instancer version and let us know if the issue continues.
     
  36. animal531

    animal531

    Joined:
    Aug 26, 2014
    Posts:
    25
    Hi,

    I've upgraded from 1.7.3 to 4 and so far I haven't seen the issue again. I'll let you know if it repeats.
    Thanks!
     
  37. KD_W

    KD_W

    Joined:
    Feb 9, 2015
    Posts:
    19
    Hi,
    I saw some comments mentioned you are making documentation and examples for using Crowd Animator with DOTS. Do you have a rough release date?
     
    Last edited: Oct 16, 2022
  38. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    We are preparing a demo scene as an example for the next update. Not specifically for DOTS, but an example of how you can use the internal arrays with Jobs to control animation states. It will probably be released next month.
     
  39. roger_peng

    roger_peng

    Joined:
    Sep 19, 2015
    Posts:
    5
    Hi,
    Is there a URP/Unlit shader for CrowdAnimation, bcause my models don't need any extra light effect.
     
  40. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    There is not an included Unlit shader. But there are setup nodes for Shader Graph that you can create shaders with. Or you can simply duplicate the Shaders/Crowd_Animations_LIT_SG shader and then change it to Unlit:
    upload_2022-10-21_10-57-9.png

    You can then use this shader on your materials.
     
    roger_peng likes this.
  41. roger_peng

    roger_peng

    Joined:
    Sep 19, 2015
    Posts:
    5
    Thanks, I will try later.
     
  42. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    After upgrading and running the URP package I got a new file called "Crowd_Animations_LIT_SG". This now gives this error when compiling:

    upload_2022-11-10_22-57-32.png

    Everything ran fine before, and if I delete the file it keep running just fine. Do I need this file?
     
  43. the_unity_saga

    the_unity_saga

    Joined:
    Sep 17, 2016
    Posts:
    273
    hi, in your demo you have the crowd not render when not in certain view of camera,

    how can I change this to not render or animate when also not in certain distance of camera or within object geometry (arbitrary polygonal shape)

    im trying to control GPU Utilization, also good work i may buy it, but this is a concern


    EDIT:

    ok i went ahead and got it,

    how do we reliably solve "Instancing has not been initialized"

    do all prefabs require the GPUInstancerPrefabRuntimeHandler component added or they dont work??


    also, it seems baked transforms are slow, no matter what asset I use, are there tips to speed this up?

    thanks
     
    Last edited: Nov 23, 2022
  44. Wolvman92

    Wolvman92

    Joined:
    Oct 31, 2021
    Posts:
    12
    Hi, is there any way that we can get official support for the Better Lit Shaders asset for those of us that don't know much about editing shader code? BLS is popular enough to make me think this would be beneficial to many people out there.
     
  45. Wolvman92

    Wolvman92

    Joined:
    Oct 31, 2021
    Posts:
    12
    Is there any way to fix the extremely dark shadow that shows up on the models once you enter play mode. It looks like anything that casts a shadow on the model is extremely amplified. So if another object casts a shadow on the model it is nearly pitch black. The side of the model opposite of the sun is also extremely black. Models that are not using GPU Instancer do not have the dark shadow on them and look correct.
     
    Last edited: Nov 24, 2022
  46. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    "Instancing has not been initialized" means that the prefab instance is not being rendered by GPU Instancer. If you have prefab instances in your scene in edit mode, you can add them to the Crowd Manager using the Register Instances in Scene button. If you are instantiating them at runtime, you can use the AddPrefabInstance API method.
    GPUInstancerPrefabRuntimeHandler component is added and required, when you enable the Auto. Add/Remove Instances option.
    Please use the Profiler to see what is causing the slow down. And if there is an issue, please email us a support request following this guide.

    Hi there,
    We can not do much on our side since we can not edit and share another assets shader. You should contact the shader developer and see if they will help. If there is anything we can do to help on our side, we will be happy to do so.

    It depends on settings, shaders, etc. I can't say anything specific without further information. Please email us a support request following this guide so we can investigate.
     
    the_unity_saga likes this.
  47. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Hi, I've been profiling my code to find out why after spawning all my characters I get 200 FPS and after 10 seconds it drops to 170fps. (I'm using the zero gameobject workflow)

    Whatever is going on happens in GPUICrowdManager.LateUpdate() which suddenly takes twice the MS after the 10 seconds. I find that weird because during that initial time my crowd prototypes are already all spawned and animated, so nothing new should be going on.

    Any idea what could be causing this? I looked at your code to gain some insight, but it's a complex system, I couldn't spot what's happening.

    UPDATE: After digging deeper it's GPUICrowdManager.LateUpdate() > UpdateAnimatorsData() > SetModifiedBuffers > ComputerBuffer.SetData > InternalSetNativeData()

    Could this be caused by changing which animation is playing on some crowd prototypes?
     
    Last edited: Dec 8, 2022
  48. EgemenJP

    EgemenJP

    Joined:
    Oct 9, 2018
    Posts:
    5
    Hi, I was tinkering with this to make it work with VFX graph and create animated effects without GPU readbacks. Seems doable but not sure how to go about it without doing some modifications; since you use ComputeBuffer but Unity seems to be moving towards GraphicsBuffer and that's the only type VFX graph currently supports... Would you be interested in adding this feature ?
     
  49. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    I can not really say what would cause this. There are too many variables that affect performance. It might even be caused by editor and act different on build or related to hardware.
    As for SetData calls, they are made every time GPUI needs to update GPU buffers such as updating animation states, moving instances etc. So there might be more or less SetData calls depending on your use case.
    In any case, if you think there might be an issue with GPUI, please email us a sample project and we can investigate.

    Hi there,
    We are working on a complete overhaul of GPUI where we also be using GraphicsBuffers (planned as a separate asset, release date TBA), but we are not planning to change to GraphicsBuffers in the current system. But you can still use your own GraphicsBuffers with your structs and copy any needed information to them from the GPUI buffers using Compute Shaders.
     
  50. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Hello GPUI Team, It's me again with another complicated question about VARIATIONS this time. This is the usual reminder that I'm using a zero gameobject workflow.

    From the example and manual, I know I can change the albedo color, but I was hoping to work with submeshes. With materials set to cutout, and changing the transparency, I could show or hide different combinations.

    I'm going down this rabbit hole because I have 300FPS with 3000 AI, BUT when I add prototypes It completely kills the performance (even though the instance count is the same). Profiling shows most of the work happening in crowd animator's buffer update. ALL my characters have the same animation controller, but I'm guessing internally you have to treat them individually because the animations are baked to the vertices of the different meshes?

    I see that internally you use material property blocks in the GPUInstancerRender class, I was wondering if your variation system works through that and if it's possible to do more than change colors. I'm thinking SetFloat, SetFloatArray, SetInt, SetTexture, SetVector, etc. If changing textures was possible, it would limit the number of submeshes I need.

    Some questions:

    1-Would the coutout/transparency technique described above work with your variation method, and if so how do I specify which submesh to apply a variation to?
    2-Using your variation method, is it possible to change other parameters beside color? (textures, custom shader values, float arrays, etc.) (your example and doc only shows color)
    3-What's the relation between CrowdAnimator and the GPUInstancerRender class, how does it currently use the material property block?
    4-If I modify your code could I access GPUInstancerRender and append properties to it's block without breaking GPUI?

    I'm facing a lot of unknowns here, I hope you can help me orient my efforts.

    If anyone has input that can help, please share.