Search Unity

propper way to change GuiText color in edit mode?

Discussion in 'Scripting' started by ratamorph, Apr 25, 2008.

  1. ratamorph

    ratamorph

    Joined:
    Sep 2, 2007
    Posts:
    458
    Hey guys, any of you know a way to change the text color of a GUIText object in edit mode?

    I usually do

    Code (csharp):
    1. @script ExecuteInEditMode()
    2.  
    3. var textColor : Color;
    4.  
    5. function Start()
    6. {
    7.     renderer.material.color = textColor;
    8. }
    But when I do this I get a warning saying that doing this will leak materials in edit mode... and of course noone wants that, so how do you guys do it?

    Sorry if the code is not 100% correct but you get the idea.
     
  2. ratamorph

    ratamorph

    Joined:
    Sep 2, 2007
    Posts:
    458
    I'd like to add that this also happens with GUITexture and 3D text, or any time I try to change the color like this on any material in edit mode.

    The warning says that I should be changing the shared materials which is fine in most cases, but what if I don't want to change the color for every model that uses that material? say I have a set of objects that use the same material and I want them to show different degrees of transparency and I want to set it up all in edit mode?

    Also shared materials doesn't seem to be public for 3D text so how would I go about changing it anyways? and what if I want to use different color for different texts? If I change shared materials somehow all the texts would change col0or.

    Again this is only and issue when I try to run the script in edit mode, so it's more of an anoyance when trying to get colors just right, I have yet to run into a serious problem as I have been ignoring the warning so far, but the fact that I might be leaking materials just worries me.
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I haven't tried what you're doing, but I know that changing color/transparency for a material actually creates a new temporary material at run-time. So this:

    is not actually possible. If you do this at run-time, you end up with a bunch of cloned materials, which go away when you stop play. Perhaps in edit mode, you're running into the problem of what to do with those cloned materials.

    (As a side note, it's nice that Unity handles this invisibly for you, but it can be a bit of a gotcha: say you're individually animating the materials for objects that are being created and destroyed during the game...over time you end up with thousands of cloned scene materials, unless you take care to keep track of the scene materials and destroy those along with the object when necessary.)

    --Eric
     
  4. ratamorph

    ratamorph

    Joined:
    Sep 2, 2007
    Posts:
    458
    I see... so everytime I change a material's color at runtime it'll create a temporary material of each change I make, so say I fade an object in I'll end up with one material per alpha change? in that case where are these stored? how do I destroy them?
     
  5. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Not really. If you modify the material (as opposed to sharedMaterial), it will instantiate this material the first time. This instantiated material becomes owned by the renderer. Further modifications to this material don't create a new copy of it.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yeah, sorry for not being clear that the temporary material is only created the first time you modify the "base" material.

    Only temporarily in the scene view. If you click on a texture pop-up while running a scene, in addition to "* Assets *", you'll find another list under "* Scene *" which is the temporary textures created (if any).

    It's possible to use FindObjectsOfType and go through the array and destroy the ones you don't need anymore, but that's often not very convenient. What I usually do if necessary is make my own copy of the sharedMaterial instead of letting Unity do it:

    Code (csharp):
    1. private var mat : Material;
    2.  
    3. function Start () {
    4.     mat = Instantiate(renderer.sharedMaterial);
    5.     renderer.material = mat;
    6.     mat.color = Color(.8, .2, .8);  // or whatever
    7. }
    8.  
    9. function OnDisable () {
    10.     Destroy (mat);  // or do this when calling Destroy(gameObject)
    11. }
    It seems to me that it might be better if Unity took care of this, but there's probably a good reason for it.

    --Eric
     
  7. ratamorph

    ratamorph

    Joined:
    Sep 2, 2007
    Posts:
    458
    ohh, not as bad as I was thinking, maybe I can script something up to destroy the material in edit mode, perhaps your code would do the job, I'll give it a shot.

    Thanks!