Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[SOLVED] Unable to reassign materials on cached renderers :\

Discussion in 'Scripting' started by TooManySugar, Mar 15, 2018.

  1. TooManySugar

    TooManySugar

    Joined:
    Aug 2, 2015
    Posts:
    864
    Hi, I'm getting totally nuts.
    I wanted to avoid direct reference to a renderer on each update cycle, so I told myself, I cache it on Start() and I call the instance in update. It seems to work until I try to assign back the materials to renderers.

    Code (CSharp):
    1.  Renderer[] wheel_rends; //all renderers under FL FR....
    on Start()

    Code (CSharp):
    1. //for Wheel and Caliper material update
    2.        
    3.         foreach (CarWheel w in car.wheels)
    4.         {
    5.             wheel_rends = w.transform.GetComponentsInChildren<Renderer>();
    6.             foreach (Renderer r in wheel_rends)
    7.             {
    8.                 Debug.Log("wheel_rends = " + r.name);
    9.             }
    10.         }      
    called from Update

    Code (CSharp):
    1.  void UpdateMaterials()
    2.     {      
    3.             // Per wheel!
    4.             foreach (CarWheel w in car.wheels)
    5.             {
    6.                 foreach (Renderer r in wheel_rends) {
    7.                     Material[] materials = r.materials;
    8.                     foreach (Material m in materials)
    9.                     {                  
    10.                     //TIRE DEFORMATION
    11.                     SetShaderFloat(m, "_SlipAngle", -w.slipAngle);
    12.                     SetShaderFloat(m, "_SlipRatio", -w.slipRatio);
    13.                     SetShaderFloat(m, "_Deflection", 0.5f);
    14.                     SetShaderFloat(m, "_SpeedRatio", Mathf.Clamp01((w.angularVelocity - 10) / 30));
    15.                                      
    16.  
    17.                     //BRAKES EMISSION
    18.                     float heat = Mathf.Clamp01(w.brakeTemp / 400);
    19.                         SetShaderColorIntensity(m, "_EmissionColor", heat);
    20.  
    21.                 }
    22.                 r.materials = materials;
    23.  
    24.             }
    25.         }
    26.     }
    If I swap wheel_rends by w.getcomponentsinchildren<Renderer>() , all works.
     
  2. jschieck

    jschieck

    Joined:
    Nov 10, 2010
    Posts:
    429
    The problem is your only caching the renderer's for the last wheel in the loop... you can see this if you do this. wheel_rends is only storing for wheel #4, the others are being replaced
    Code (CSharp):
    1. // caches only the renderers for the last wheel...
    2. int currentWheel = 0;
    3. foreach (CarWheel w in car.wheels)
    4. {
    5.     wheel_rends = w.transform.GetComponentsInChildren<Renderer>();
    6.     foreach (Renderer r in wheel_rends)
    7.     {
    8.         Debug.LogFormat("wheel_rends for wheel {0}={1}",currentWheel, r.name);
    9.     }
    10.     currentWheel++;
    11. }
    You need to store the renderers for each wheel separately, like in a dictionary or something similar
    Code (CSharp):
    1. // store the renderers for each wheel in a dictionary
    2. Dictionary<CarWheel, Renderer[]> wheelRenderers = new Dictionary<CarWheel, Renderer[]>();
    3. foreach (CarWheel w in car.wheels)
    4. {
    5.     wheelRenderers.Add(w, w.transform.GetComponentsInChildren<Renderer>());
    6. }
    7.  
    8.  
    9.  
    10. // In Update
    11. // Per wheel!
    12. foreach (CarWheel w in car.wheels)
    13. {
    14.     Renderer[] wrs = wheelRenderers[w];
    15.     for (int i = 0; i < wrs.Length; i++)
    16.     {
    17.         Renderer r = wrs[i];
    18.         // do stuff
    19.     }
    20. }
    21.  
     
    TooManySugar likes this.
  3. TooManySugar

    TooManySugar

    Joined:
    Aug 2, 2015
    Posts:
    864
  4. TooManySugar

    TooManySugar

    Joined:
    Aug 2, 2015
    Posts:
    864
    Thanks for the detailed solution.
    Definitelly the dictionary looks like the way to go.
    Never tried before but may be an array could be nested within an array (in case this is faster).

    TX!