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. Dismiss Notice

What Am I Doing Wrong?

Discussion in 'Scripting' started by DRRosen3, Nov 30, 2014.

  1. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class Ball: MonoBehaviour {
    6.  
    7.     public Material captureColor;
    8.    
    9.     private Renderer[] renderers;
    10.     private Material[] materials;
    11.  
    12.     void Start() {
    13.     }
    14.  
    15.     void Update(){
    16.     }
    17.  
    18.     void OnCollisionEnter(Collision col){
    19.       renderers = col.gameObject.GetComponentsInChildren<Renderer>();
    20.       foreach(Renderer renderer in renderers){
    21.                 materials = renderer.materials;
    22.                 for(int m = 0; m < materials.Length; m++){
    23.                     materials[m] = captureColor;
    24.                 }
    25.           }
    26.      }
    27.  
    28. }
    29.  
    What's supposed to happen is that when the GameObject this script is attached to collides with another GameObject it's supposed to change that ENTIRE GameObject (that it collided with) to the "captureColor" material. It's not doing anything. The reason I'm trying to use a nested loop to do this is because some of the GameObjects have renderers with multiple materials on one renderer.
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Assign the materials back to the renderer.

    --Eric
     
    DRRosen3 likes this.
  3. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    So it should be:

    renderer.materials[m] = captureColor;

    If so, that didn't work either.
     
  4. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    No, Get the array and change each one (like you are), then set the whole array back into .materials
     
    DRRosen3 likes this.
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    I mean assign the materials array back to renderer.materials when the loop is done.

    --Eric
     
    DRRosen3 likes this.
  6. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Alright guys. Help me out. What's the line of code? Usually I don't ask for a precise answer like that, but I can't figure it out. v.v

    EDIT - Never mind guys. I figured it out. I accidentally wrote... (The error I made is on Line 4.)

    Code (CSharp):
    1. foreach(Renderer renderer in renderers){
    2.                 materials = renderer.materials;
    3.                 for(int m = 0; m < materials.Length; m++){
    4.                    renderer.materials[m] = captureColor;
    5.                 }
    6.                 renderer.materials = materials;
    7.             }
    When it SHOULD have been...

    Code (CSharp):
    1. foreach(Renderer renderer in renderers){
    2.                 materials = renderer.materials;
    3.                 for(int m = 0; m < materials.Length; m++){
    4.                     materials[m] = captureColor;
    5.                 }
    6.                 renderer.materials = materials;
    7.             }
     
  7. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Well while this thread is new and fresh, I guess I could also ask the second part I'm struggling with. At the end of this same script, I need to change the GameObject (the one that was changed) back to its original materials. I'm quite sure I want to use the "renderer.materials.CopyTo" method, but I'm not sure how to go about executing this. Not to mention, as stated before, different GameObjects in the game have different amounts of renderers, so I won't know ahead of time exactly how many copies need to be made. Think anybody can get me started or point me in the right direction?
     
  8. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Luckily, as stated in the docs
    http://docs.unity3d.com/ScriptReference/Renderer-materials.html
    Note that like all arrays returned by Unity, this returns a copy of materials array
    So you should just be able to do
    Material[] originalMaterials = renderer.materials;
    Before editing, then assign that one back to revert
     
  9. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Sweet! Now would this still work the same for GameObjects with multiple renderers? Will that line of code ( Material[] originalMaterials = renderer.materials; ) get every single renderer on the GameObject and every single material for each renderer?
     
    Last edited: Dec 1, 2014
  10. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    One Gameobject can't have multiple renderers

    renderer.xxx will only be pointing to a single renderer

    If it's renderers of children of a parent object, you'll need to iterate over them, and make a list<Materials[]>.... or something
     
    DRRosen3 likes this.
  11. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    682
    Yeah... Sorry. I wasn't clear on that. They're children GameObjects. Thanks for the help!