Search Unity

[RELEASED] GPU Instancer - Crowd Animations

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

  1. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    Unfortunately I am only able to provide you the following information:

    Unity: 2020.3.30f1
    URP: 10.8.1
    Screen Shot 2022-04-24 at 7.41.07 PM.png Screen Shot 2022-04-24 at 7.41.00 PM.png Screen Shot 2022-04-24 at 7.40.49 PM.png

    Sorry for the inconvenience.
     
  2. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    The name of the shader that needs the fix is

    Crowd_Animations_LIT_SG
     
  3. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    I tried to reproduce it with the same Unity/URP version and with the same manager settings, but there were no issues. If you are using preview packages of Unity, most probably the issue is caused by them. If you can email us a sample project, we can investigate further. However as it stands we can not incorporate this change into the asset, since it would cause issues for users who do not use those unity packages.
     
    Abbrew likes this.
  4. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,148
    Hey guys,

    i'm a bit confused. I wonder, if i want to get the "GPU Instancer - Crowd Animations" do i have to pay for both "GPU Instancer" and "GPU Instancer - Crowd Animations" or there is some upgrade price !?

    It seems that if i want to use the crowd extension i'm forced to pay full price for both assets even if i don't need the full functionality of "GPU Instancer". Is that correct !?
     
  5. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    Crowd Animations is an expansion pack for GPU Instancer, it is not an upgrade. So there is not a discount for owning one of them and you need both packages to use Crowd Animations.
     
  6. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    StartAnimation API method can be run with an AnimationClip. If you are using a no-GO workflow, same overrides that take an AnimationClip parameter also exist within the GPUICrowdAnimator class.

    I was not able to reproduce this issue on our side. Can you please email us a sample project (e.g. a scene with minimum amount of content to show the problem), so we can investigate?
     
  7. Plnda

    Plnda

    Joined:
    Nov 23, 2016
    Posts:
    14
    Hi could you tell me what was broken on the Oculus Quest 2? it seems to work perfectly fine, the only thing i discovered is that the Animation events wont properly send out the string values i set to them (2021.3LTS)
     
  8. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    About Oculus Quest please see the reply at this post.
    As for the animation events, if you can email us a sample project, we can investigate it.
     
  9. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    So I pass it an animationclip and it knows what clip in the crowd animator to play? Not sure what you mean by a no-go workflow, DOTS?

    I know I can start it like this using crown animator:

    crowdPrefab.StartAnimation(crowdPrototype.animationData.clipDataList[index]);


    But then I need to keep track of the index, which can change when I add more animations.
     
  10. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    You are using this method:
    StartAnimation(GPUIAnimationClipData clipData) 

    there is also this:
    StartAnimation(AnimationClip animationClip) 


    Simply use the AnimationClip instead of the GPUIAnimationClipData:
    crowdPrefab.StartAnimation(myAnimationClip); 


    As for the No-GameObject workflow, you can see more information here. There is also a demo scene called NoGameObjectsDemo.
     
    mrCharli3 likes this.
  11. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    Adding a transition time when using StartAnimation seems to break something, no errors.

    Without transition time I can switch between animations without any issues, however once I add a 0.5f transition time, the animation starts playing, but stops in place after 0.5-1 seconds. Am I missing something or is this bugged?

    crowdPrefab.StartAnimation(clip, -1, -1, .5f);


    Second question, is blending ment to be used when I want to play more than one animation at a time, lets say running + punching?

    Solved, Im an idiot:

    FIX:
    crowdPrefab.StartAnimation(clip, -1, 1, .5f);
     
    Last edited: May 11, 2022
  12. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    How do I disable a mesh at runtime? Disabling the child-object containing the skinned mesh renderer does not actually made the mesh stop rendering.

    I alos dont see the optional renderer checkbox:

    upload_2022-5-12_14-49-6.png
     
  13. ThatGoKu

    ThatGoKu

    Joined:
    May 8, 2018
    Posts:
    5
    I need this usage!

    I have a model with different weapons and armor, by combining different weapons and armor to generate multiple different monsters. I baked the weapon and character skins together using the MeshBaker plugin and instantiated them using GPUI. The problem was that model with different looks could not reuse animation bake files. I hope to have an example and tutorial to implement this feature.
     
  14. GurhanH

    GurhanH

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

    Optional renderers option would only show when there are multiple SkinnedMeshRenderer components. If you have only one, and want to disable it without disabling the parent GO, you can use the DisableIntancingForInstance API method.

    Hi there,
    thank you for the feedback.
    If you only need to set them in editor mode, you can do so from the Baked Animation Data property:
    upload_2022-5-13_18-14-35.png

    If you want to add new prototypes with the same baked data at runtime, you can use the DefineGameObjectAsCrowdPrototypeAtRuntime API method.
     
  15. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    When I add the GPUI prefab manager to a scene with GPUI Crowd manager and hit play, all my crowd prefabs stop rendering. They go invisible?
     
    Last edited: May 13, 2022
  16. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Possibly caused by an incorrect setup while using the same prefab in different managers. If you are using the Prefab Manager for bone attachments, you should only use the attached object as a prototype for the Prefab Manager.
    For example if you have a character with a weapon:

    Character <- This will be the prototype for the Crowd Manager
    SkinnedRenderer
    root
    spine
    leftArm
    MyWeapon <- This will be the prototype for the Prefab Manager

    Prototypes for Crowd Manager will have GPUI Crowd Prefab script attached to them. And the prototypes for the Prefab Manager will have GPU Instancer Prefab script attached to them.

    Please check if you have the correct setup and if it does not solve the issue, please send us a sample project.
     
    mrCharli3 likes this.
  17. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    If I have 5 optional renderers, does that mean I need 5 baked textures?

    i.e I do not really save any memory by "sharing" animations between meshes with the same rig. So it would be better to keep them split and bake them with only the required animations for each mesh. Is that correct or is the asset smart enough to only use 1 baked texture even if you have several optional renderers?
     
  18. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
  19. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    It think you are confusing two different cases.
    Optional Renderers are for cases where you have multiple SkinnedMesh renderers for a character where each instance can use a different combination of them. For example when you have different hair-clothes etc. for each character:
    Code (CSharp):
    1. Character
    2.     Hair1
    3.     Hair2
    4.     Clothes1
    5.     Clothes2
    6.     Body1
    7.     Body2
    You can see an example usage in the OptionalRenderersDemo scene. In this case, there is only one baked texture.

    The other case is that you can share baked data between two prototypes when they are using the same rig, but different meshes:

    Code (CSharp):
    1. Character1
    2.     Mesh1
    3.  
    4. Character2
    5.     Mesh2
    In this case, if you used the same baked data for both prototypes, they will use the same texture for GPU skinning.
     
    mrCharli3 likes this.
  20. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    There is a third scenario, where you keep the animator empty and do this:

    Code (CSharp):
    1. Animator
    2.     CharacterMesh1
    3.     CharacterMesh2
    4.     CharacterMesh3
    5.     CharacterMesh4
    6.  
    Where each is an optional renderer. This is the option I am using.
     
  21. daoviettuan2002

    daoviettuan2002

    Joined:
    Nov 5, 2018
    Posts:
    9
    Can I use prototype prefab with addressable?
     
    Last edited: May 21, 2022
  22. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    This would be technically the same with the first scenario.

    It is possible, however GPUI does not have out of the box support for addressables. So you would need to load the prefabs/prototypes before loading any of the managers. But we do not currently have demos or documentations specific to Addressables.
     
  23. daoviettuan2002

    daoviettuan2002

    Joined:
    Nov 5, 2018
    Posts:
    9
    I got it. Tks.
    I have another question: Which is better between mecanim animator and Cownd animator?
    And Which is better between Have Gameobject and No-gamebject?
    Please tell me.
     
    Last edited: May 26, 2022
  24. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Yes, you can use the DefineGameObjectAsCrowdPrototypeAtRuntime API and make sure that the baked animation data is packed together with the prefab.
     
  25. 957255029_zcb

    957255029_zcb

    Joined:
    Mar 17, 2022
    Posts:
    3
    I want to change crowdPrefab color in Game....but,it can't to be...

    Code (CSharp):
    1.  public void SingleChangeColor1()
    2.     {
    3.         Debug.Log("-------Method1");
    4.         SkinnedMeshRenderer[] meshRenderers = _instanceList[0].GetComponentsInChildren<SkinnedMeshRenderer>();
    5.         foreach (SkinnedMeshRenderer mr in meshRenderers)
    6.         {
    7.             MaterialPropertyBlock mpb = new MaterialPropertyBlock();
    8.             mr.GetPropertyBlock(mpb);
    9.             mpb.SetColor("_BaseColor", Color.green);
    10.             mr.SetPropertyBlock(mpb);
    11.         }
    12.  
    13.  
    14.         Debug.Log("-------Method2");
    15.         GPUInstancerAPI.UpdateVariation(gpuiCrowdManager, _instanceList[0], "colorBuffer", Color.green);
    16.  
    17.  
    18.         Debug.Log("-------Method3");
    19.         // GPUICrowdAPI.ChangeMaterial(gpuiCrowdManager, _instanceList[0], material)
    20.     }
     
  26. daoviettuan2002

    daoviettuan2002

    Joined:
    Nov 5, 2018
    Posts:
    9
    I have 2 prefabs with the same Rig(bone), but difference Mesh, Texture. So I must bake animation for each prefab or I can use them same bake animation data? I saw the animation data have ~4Mb, if make too much animation data will lost more memory and heavy.
     
  27. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    You can not use material property blocks to make instance based variations while using indirect GPU instancing. All of the instances share a single material property block. For using instance based variations with GPUI, please see Material Variations documentation. There are also demo scenes in the package that exemplifies this.

    Hi there,
    Please see this post and this post for information about this.
     
  28. 957255029_zcb

    957255029_zcb

    Joined:
    Mar 17, 2022
    Posts:
    3
    Thank you very much for your reply. I will check the document
     
  29. 957255029_zcb

    957255029_zcb

    Joined:
    Mar 17, 2022
    Posts:
    3
    If my shadergroup have tow "GPUI Float4 Variation",but my bufferName "gpuiFloat4Variation" Only one...
    I can't use it to separately change tow value...if you miss my idea... talk me some help..thanks
     
  30. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    the "GPUI Float4 Variation" node is an example. If you want to use multiple buffers or different value types, you need to create new nodes using this as an example.
     
  31. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    Q1: Lets say I have 500 agents using a variation of 10 different meshes (swordman, worker, archer, etc) and they all share rigs. Would it be more performant to pack 1 texture for each mesh with their specific animations, or would it be better to pack 1 large texture with all animations and share it across all those agents? Keeping in mind that a lot of animations are used for all (idle, walk, death), while only a few are specific.

    Q2: Do you have a recommended workflow to deal with updating/adding/editing animations? Currently when we import a new .fbx with all animations we have to delete the current prefab from the GPUI manager and re-add it.
     
  32. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    Bug: When I click "register instances" on my crowd manager it registers them properly, but it resets when entering playmode causing registered instances to be 0 and no animation to work.

    If I delete the prefab containing crowd manager and add a new object and attach crowd manager, it works fine.

    I cannot send repro project, too big.
     
    Last edited: May 31, 2022
  33. ThatGoKu

    ThatGoKu

    Joined:
    May 8, 2018
    Posts:
    5
    How to register optional renderer prototype (same as the demo prefab ZomBunnyParts) at runtime? I have some baked optional renderer prefab, and want to register and instantiate at runtime.
    below is my code, it works when first prefab register, but it work fail when second prefab register after delay, all instance miss and get wrong.

    I think GPUInstancerAPI.InitializeGPUInstancer clear all instance when I register the second prefab, but which API should I use to register and init prototype runtimedata?
    I try to use
    GPUInstancerRuntimeData InitializeGPUInstancer(GPUInstancerPrefabManager prefabManager, GPUInstancerPrefabPrototype prototype), but it not work at all.

    Code (CSharp):
    1. public class DemoMillionMonster : MonoBehaviour
    2.     {
    3.         public GPUICrowdManager CrowdManager;
    4.         public GameObject prefab;
    5.         public GameObject prefab2;
    6.         public int row = 30;
    7.         public int line = 30;
    8.         public int index = 0;
    9.  
    10.         private Transform _parentTranform;
    11.  
    12.         #region test
    13.         private async void Start()
    14.         {
    15.             _parentTranform = (new GameObject("Crowd Instances")).transform;
    16.  
    17.             await Task.Delay(1000);
    18.             RegisterPrefab(prefab);
    19.             GeneratePlayer(prefab, Vector3.zero, row, line);
    20.  
    21.             await Task.Delay(5000);
    22.             RegisterPrefab(prefab2);
    23.             GeneratePlayer(prefab2, new Vector3(0,3,0),  row, line);
    24.         }
    25.  
    26.         public void RegisterPrefab(GameObject prefab)
    27.         {
    28.             GPUICrowdPrototype crowdPrototype = (GPUICrowdPrototype)prefab.GetComponent<GPUICrowdPrefab>().prefabPrototype;
    29.             GPUInstancerAPI.AddPrototoypeToManager(CrowdManager,crowdPrototype);
    30.  
    31.             if (crowdPrototype.hasOptionalRenderers) //copy from CrowdManager
    32.             {
    33.                 SkinnedMeshRenderer[] skinnedMeshRenderers = crowdPrototype.prefabObject.GetComponentsInChildren<SkinnedMeshRenderer>(true);
    34.                 foreach (GPUISkinnedMeshData smd in crowdPrototype.animationData.skinnedMeshDataList)
    35.                 {
    36.                     if (smd.isOptional && !smd.isOptionalPrototypeGenerated)
    37.                     {
    38.                         foreach (SkinnedMeshRenderer skinnedMeshRenderer in skinnedMeshRenderers)
    39.                         {
    40.                             if (skinnedMeshRenderer.gameObject.name.Equals(smd.transformName))
    41.                             {
    42.                                 GPUICrowdPrototype generatedPrototype = CrowdManager.DefineGameObjectAsCrowdPrototypeAtRuntime(skinnedMeshRenderer.gameObject, crowdPrototype.animationData, false,
    43.                                     crowdPrototype);
    44.                                 generatedPrototype.hasOptionalRenderers = false;
    45.  
    46.                                 generatedPrototype.enableRuntimeModifications = true;
    47.                                 generatedPrototype.addRemoveInstancesAtRuntime = false;
    48.                                 generatedPrototype.isChildPrototype = true;
    49.                                 generatedPrototype.parentPrototype = crowdPrototype;
    50.                                 generatedPrototype.autoUpdateTransformData = false;
    51.                          
    52.                                 smd.isOptionalPrototypeGenerated = true;
    53.                                 smd.optionalPrototype = generatedPrototype;
    54.                                 break;
    55.                             }
    56.                         }
    57.                     }
    58.                 }
    59.             }
    60.             GPUInstancerAPI.InitializeGPUInstancer(CrowdManager,true);
    61.         }
    62.  
    63.         public void GeneratePlayer(GameObject prefab, Vector3 offset, int row, int colum)
    64.         {
    65.             GameObject prefabObject = prefab;
    66.             for (int i = 0; i < row; i++)
    67.             {
    68.                 for (int j = 0; j < line; j++)
    69.                 {
    70.                     //Debug.Log("generate "+i+" "+j);
    71.                     var pos = new Vector3(i * 2 - 20, 0, j * 2 -20) + offset;
    72.                     spawnInstance(prefabObject, _parentTranform, pos);
    73.                 }
    74.             }
    75.         }
    76.  
    77.         public void spawnInstance(GameObject prefabObject, Transform parent, Vector3 pos)
    78.         {
    79.             GameObject instanceGO = Instantiate(prefabObject, pos, Quaternion.identity, parent);
    80.             GPUICrowdPrefab crowdPrefab = instanceGO.GetComponent<GPUICrowdPrefab>();
    81.             GPUInstancerAPI.AddPrefabInstance(CrowdManager, crowdPrefab,true);
    82.         }
    83.  
    84.         #endregion
    85.  
    86.     }
     
    Last edited: Jun 1, 2022
  34. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    1- One prototype that renders all would be the best in most cases. All processes would be batched together and executed in one call.
    2- You should be able to re-bake the animations when you edit them. But if you have a special workflow, you can access the animation clip list from GPUICrowdPrototype.clipList.

    I am not sure what exactly is causing the problem. However, you should not make GPUI managers prefabs. They have references to objects in scene, which would be lost when saved as a prefab and cause issues. Managers should be saved in scene, or created through scripts at runtime.

    Hi there,
    and thank you for sharing the sample code.
    It should work if you replace the AddPrototoypeToManager with DefineGameObjectAsCrowdPrototypeAtRuntime:
    Code (CSharp):
    1. public void RegisterPrefab(GameObject prefab)
    2. {
    3.     GPUICrowdPrototype crowdPrototype = (GPUICrowdPrototype)prefab.GetComponent<GPUICrowdPrefab>().prefabPrototype;
    4.     CrowdManager.DefineGameObjectAsCrowdPrototypeAtRuntime(prefab, crowdPrototype.animationData, false);
    5.  
    6.     if (crowdPrototype.hasOptionalRenderers) //copy from CrowdManager
    7.     ...
    We will also look into making DefineGameObjectAsCrowdPrototypeAtRuntime work with optional renderers without additional code in a future update.
     
  35. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Additionally if you encounter this error:
    "InvalidOperationException: The NativeArray has been deallocated, it is not allowed to access it"

    Please edit the GPUICrowdOptionalRendererHandler.cs line 38
    from this:
    Code (CSharp):
    1. if (_crowPrefab.state == PrefabInstancingState.Instanced)
    to this:
    Code (CSharp):
    1. if (_crowPrefab.state == PrefabInstancingState.Instanced && _crowPrefab.runtimeData.instanceDataNativeArray.IsCreated)
    which should solve the problem. We will also add this check to the next update.
     
  36. ThatGoKu

    ThatGoKu

    Joined:
    May 8, 2018
    Posts:
    5
    I have a suit model use different equip (mesh render) and same body skinnedrenderer, I use plugins to combine into one skinnedmeshrender that use same animation and material but different mesh, when I use DefineGameObjectAsCrowdPrototypeAtRuntime in order to reuse the animationData, but it not work, it looks wrong.


    Then I combine all prefab into one, and use optional skinned to switch which look should be appear, It works.

    But there are an other problem, I need to change the equip color at every instance, but it looks like that then material varient did't not work with optional renderer. So what should I do?
     
    Last edited: Jun 2, 2022
  37. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    I will need to make some tests to reproduce these issues. Can you please email us detailed information about your setup following this guide, and if possible also send a sample project?
     
  38. SOSolacex

    SOSolacex

    Joined:
    Jan 10, 2018
    Posts:
    121
    Hi, I am having an issue where sometimes enabling/disabling a gameobject with an animation for some reason resets it to its default animation rather than just playing the correct one. I tried reinitializing the correct animation after being re-enabled however it doesn't really seem to work.
     
  39. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    Please email us a sample project where we can see this issue, so we can investigate.
     
  40. YTGameDevDave

    YTGameDevDave

    Joined:
    Jan 3, 2015
    Posts:
    13
    Hey guys how's the support coming along for mobile and VR? (Quest 2)
     
  41. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Hi there,
    Please read this for information on this subject.
     
  42. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    @GurhanH Animation events for the crowd animations are unpredictable at x3 timescale. It works perfectly at x1 timescale and plays exactly when+where it should, however at 3x timescale it plays at the wrong frame, causing it to play in the wrong position (since I base position on the vfx played at the event on the item being controlled by the animation movement).

    upload_2022-6-23_10-5-3.png

    This should be quite easy to reproduce, this is something I really need a fix for or I cannot use the asset.
     
  43. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    393
    @GurhanH, I'm having some issue with making the LOD work with the crowds-extension.

    I have an FBX model of a human, skinned in 3ds max. It's made of LOD0, LOD1, LOD2 meshes.
    They have 1 animation clip animate correctly via unity's animator system.

    However, after baking the animations only LOD0 behaves correctly. The other LODs deform incorrectly around arms and legs, kinda rotated by 90 degrees. :(
    In the import settings (Rig) They are Humanoid, but the issue occurs even if Generic.

    I've been testing for few days, but no luck; Could you please have a look what could be causing the LOD issue, it only occurs when Baking the animations in GPUI Crowd Manager: https://www.dropbox.com/s/vlffi81hbt1a0ut/AdultMale_reskin.fbx?dl=0

    Your provided chomper model behaves correctly, including LODS. I strongly suspect it has to do with 3ds max axis, where z is up, versus Blender axis, where y is up.

    Thank you!
     
    Last edited: Jun 27, 2022
  44. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    Crowd Animations makes the event calculations every update. When you have 3x timescale and less than 3x FPS than the baked frame rate, then the events might not fire exactly at the specified frame, because multiple animation frames will be passing between updates.
    As a workaround, you can Simulate the time delay for your vfx, for example, using the GetAnimationTime API method.

    Hi there,
    It looks like these skinned meshes have different bind poses. Crowd Animations can handle bind pose offsets (e.g. position, rotation differences) between meshes when it is the same offset for all bones. But these meshes have different offsets for bones, suggesting that the bones were modified while making the LODs. These LODs also did not work correctly without Crowd Animations in my tests when used with an LOD Group component. So I think the issue is about how the LODs were made in the modelling program. You need to use the same bone structure without modifications for LODs to work correctly with the same rig.
     
    IgorAherne likes this.
  45. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    976
    Is there a way to check if an Instance is currently being culled? Similar to
    Renderer.IsVisible
    ?
     
  46. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    According to the Wiki, there should be a Has Optional Renderers option. This is what the inspector should look like



    However, it is not showing up in my inspector. Here's what my inspector looks like:


    Is there somewhere else I can configure optional renderers?
     
  47. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    I've given up trying to have optional GameObjects, and instead opted for a different method.
    1. Have a GPUInstancerPrefabManager register the attachments
    2. In a Monobehavior, instantiate the attachment prefab and add it to the manager in Start()
    3. Attach the attachment to a Crowd Instance's exposed Bones. Only the bones which support attachments will be checked.

    Is this around the same level of performance as Optional GameObjects?
     
  48. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    No, unfortunately. All visibility calculations are made in GPU and is not read back to CPU (which would be very slow).

    Has Optional Renderers option is available when there are multiple Skinned Mesh Renderers under the prefab. It is also not available when there is an LOD Group, since then the LOD Group controls which renderers are visible.
    So if you have only one Skinned Mesh Renderer or an LOD Group, it would not show.

    If you are using Mesh Renderers (not skinned), you need to use the Prefab Manager, so this is the correct way.
    Crowd Manager handles the Skinned Mesh Renderers, Prefab Manager handles the Mesh Renderers. Optional Renderers is not for bone attachments, instead for cases when there are multiple Skinned Meshes that you need to enable/disable at runtime (e.g. different clothes, body parts, etc.).

    We will look into making the documentation clearer on this subject.
     
  49. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    Thank you. The prefab did indeed have LOD Groups.

    Thank you for the clarification. One question left though - which of the aforementioned workflows is more performant?
    1. Expose Bones in Crowd Manager + Separate Prefab Manager equipment as children of those body part bones
    2. Optional Renderers in Crowd Manager + All possible equipment baked, but only one for each body part enabled.

    The tentative parameters of the prefabs I'll be using are:
    1. A single "naked body" mesh that will always be managed by Crowd Manager.
    2. Around 10 body parts to which equipment can be attached
    3. There is the concept of a soldier "type" (Hoplite, Marine, Wizard, for example). There may be around 150 soldier types
    4. Each soldier type will have around 2 to 4 randomized equipment per body part, or no equipment for that body part at all. For example, a Wizard might have Blue Robes for the torso (out of Blue, Black, Red), Ice Staff for the weapon (out of Ice, Fire, Earth), but nothing else for other body parts. These will either be managed through workflows #1 or #2. Basically, as Crowd Manager Optional Renders, or Prefab Manager children attached to Crowd Manager Exposed Bones
     
  50. GurhanH

    GurhanH

    Joined:
    Apr 24, 2017
    Posts:
    539
    If you have the option to use regular meshes (not skinned) for these equipment, then use the Prefab Manager. Skinned meshes will always be slower because it has to do additional operations to apply skinning.

    But depending on your character model, some equipment might have to use skinning (e.g. clothes, hair, etc.) when they need to change shape according to animation. In that case you can't use the Prefab Manager for them, so you can use Optional Renderers with Crowd Manager.

    In conclusion:
    - Do not use skinned meshes when it is not necessary.
    - If there are many instances of an equipment (not skinned), then use the Prefab Manager to render them.
    - If the equipment has to be skinned and is optional, then use Optional Renderers in Crowd Manager.
     
    Abbrew likes this.