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

Color extension methods

Discussion in 'Scripting' started by Sock Puppet, Jul 28, 2012.

  1. Sock Puppet

    Sock Puppet

    Joined:
    Jan 9, 2011
    Posts:
    77
    I'm trying to write a couple of extension methods for the Color class.

    Although awkward, this works....

    Code (csharp):
    1.  
    2. public static void SetAlpha(this Color color, float alpha)
    3. {
    4.     Color newColor = color;
    5.     newColor.a = alpha;
    6.     color = newColor;
    7. }
    8.  
    This doesn't....

    Code (csharp):
    1.  
    2. public static void SetRGB(this Color color, float r, float g, float b)
    3. {
    4.     Color newColor = color;
    5.     newColor.r = r;
    6.     newColor.g = g;
    7.     newColor.b = b;
    8.     color = newColor;
    9. }
    10.  
    Anyone know why?
     
  2. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    Color is a Value Type (Struct) not a reference type (Class). so when passing in the instance of color it gets copied and the original instance is not changed.
    thats why i think that your first example with alpha also does not work like you think it does.
    however, you can try to get around this by unboxing but i havent tried myself. so if you find a solution please share it.
    the other possibility i can think of could be to to explicitely pass the original instance as an ref or out parameter a second time. so albeit ugly this could also work (quick idea code without ide).
    Code (csharp):
    1.  
    2. public static void SetRGB(this Color color, ref Color color, float r, float g, float b)
    3. ...
    4. Color mygreen = new Color(0.0f, 1.0f, 0.0f)
    5. mygreen.SetRGB(ref mygreen, 0.0f, 0.5f, 0.0f);
    6.  
     
  3. Default117

    Default117

    Joined:
    Mar 13, 2011
    Posts:
    134
    This is an extension class meaning he's not passing in the colour as a reference into this function and he's not trying to return a colour either.
    Sock Puppet, what is actually the problem with the second function?
     
  4. Sock Puppet

    Sock Puppet

    Joined:
    Jan 9, 2011
    Posts:
    77
    Yep its nothing to do with value types as I've got a plenty of extensions for Vector2 / Vector3's and they work fine.

    The problem with the second function is that the values don't get changed it stays as the original value.

    Code (csharp):
    1.  
    2. // Works - changes to red
    3. Color someColor = Color.white;
    4. someColor.r = 1;
    5. someColor.g = 0;
    6. someColor.b = 0;
    7.  
    8. // Doesn't - stays white
    9. Color otherColor = Color.white;
    10. otherColor.SetRGB(1, 0, 0);
    11.  
    12. // Does work...
    13. otherColor.SetAlpha(0.5f);
    14.  
     
  5. GDFenna

    GDFenna

    Joined:
    Jul 6, 2012
    Posts:
    1
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public static class MyFuncs
    5. {
    6.     //Extensions
    7.    
    8.     //Color holds copy not reference!(Will not change Value, only Read Value)
    9.    
    10.     //Material
    11.     public static void MaterialColorToRandom( this Material MaterialToChange)
    12.     {
    13.         MaterialToChange.color = new Color(Random.Range(0,0.9f),Random.Range(0,0.9f),Random.Range(0,0.9f),1);
    14.         Debug.Log("Color Change");
    15.     }
    16.    
    17.     //Transform
    18.     public static void ResetTransform(this Transform TransformToChange)
    19.     {
    20.         TransformToChange.position = Vector3.zero;
    21.         TransformToChange.rotation = Quaternion.identity;
    22.         TransformToChange.localScale = new Vector3(1,1,1);
    23.     }
    24.    
    25. }
     
  6. Errorsatz

    Errorsatz

    Joined:
    Aug 8, 2012
    Posts:
    555
    You can't pass a reference into an extension function, AFAIK. What you can do instead is either change how the function is used, or make it an extension of the containing object.

    Method A:
    Code (csharp):
    1. public static Vector3 WithX ( this Vector3 vec, float newX )
    2. {
    3.   vec.x = newX;
    4.   return vec;
    5. }
    6. ...
    7. transform.position = transform.position.WithX(0f);
    Method B:
    Code (csharp):
    1. public static void SetPositionX ( this Transform tr, float newX )
    2. {
    3.   tr.position = new Vector3(newX, tr.position.y, tr.position.z);
    4. }
    5. ...
    6. transform.SetPositionX(0f);
     
    rakkarage likes this.
  7. blueknee

    blueknee

    Joined:
    Apr 5, 2014
    Posts:
    8
    Since this post comes up first on google...
    My solution is to extend SpriteRenderer which contains Color.
    It worked for me.
    Code (csharp):
    1.  
    2. public static void SetAlpha(this SpriteRenderer self, float alpha)
    3. {
    4. Color next = self.color;
    5. next.a = Mathf.Clamp01(alpha);
    6. self.color = next;
    7. }
    8.  
     
    Alex__ likes this.