Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Need SetSharedMaterials/SetMaterials methods on Renderers to avoid allocations

Discussion in 'General Graphics' started by Prodigga, Nov 23, 2018.

  1. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,122
    Hi there

    There is a GetMaterials and GetSharedMaterials method which lets you pass in your own List<Material> so that you can avoid allocating garbage when fetching the material list on a Renderer.

    But without a SetMaterials and SetSharedMaterials method, this is useless because we need to convert this list to an array if we ever want to alter the materials on a renderer. The only way to set the materials is via 'renderer.sharedMaterials' or 'renderer.materials' setters, which both take arrays.
     
    pointcache likes this.
  2. pointcache

    pointcache

    Joined:
    Sep 22, 2012
    Posts:
    576
    Agree should at least have a variant with NoAllocHelpers.ExtractArrayFromList(values)
     
  3. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,122
    Why do I feel like this is going to be one of those "advanced features" don't won't gain enough traction with the community to ever get implemented? :p Hopefully a Dev can respond here directly to give me some hope !
     
  4. kingstone426

    kingstone426

    Joined:
    Jun 21, 2013
    Posts:
    43
    Sorry to necro this old thread but I just ran into this today.

    Would caching both the list and the array prevent allocations?

    Code (CSharp):
    1. private Renderer targetRenderer;
    2. private Material[] cachedMaterialArray;
    3. private List<Material> cachedMaterialList;
    4.  
    5. void SetMaterial(int index, Material newMaterial)
    6. {
    7.    targetRenderer.GetSharedMaterials(cachedMaterialList);
    8.    cachedMaterialList.CopyTo(cachedMaterialArray);
    9.    cachedMaterialArray[materialIndex] = newMaterial;
    10.    targetRenderer.sharedMaterials = cachedMaterialArray;
    11. }
     
  5. Liam2349

    Liam2349

    Joined:
    Mar 10, 2016
    Posts:
    75
    Yes, it would prevent managed allocations aside from possible list resizing.