Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

[SOLVED] Rainbow hue shift over time C# script

Discussion in 'Scripting' started by toasthat, Sep 2, 2015.

  1. toasthat

    toasthat

    Joined:
    Sep 2, 2015
    Posts:
    2
    I'm not a very experienced coder, I just spent all day trying to get this to work and it's driving me nuts.

    I'm trying to figure out how to get the background texture of my game to hue shift infinitely over time to create a rainbow effect, I have no idea how to do so.
    I've extensively googled this problem, but all the scripts I found were either in Java or too complicated for me to understand how to implement them.
    Also, I've downloaded the HSBColor and Colorx plugins from the unify community wiki, but I don't know how to use them to achieve this rainbow effect.

    This background is a Quad with my background texture applied to it, using the default sprite shader.

    Can anybody help me achieve this rainbow effect?

    Here's the code I have so far, though at this point I'm almost certain it's useless:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class HueShifter : MonoBehaviour {
    5.  
    6.     public Color[] colors;
    7.  
    8.     private Renderer rend;
    9.     private int rainbowPicker;
    10.     private Color newColor;
    11.     private float delay;
    12.  
    13.     void Start()
    14.     {
    15.         rend = GetComponent<Renderer>();
    16.         rainbowPicker = 0;
    17.         newColor = rend.material.color;
    18.     }
    19.  
    20.     void Update()
    21.     {
    22.         Debug.Log (Time.time);
    23.  
    24.         newColor = Colorx.Slerp (colors[rainbowPicker], colors[rainbowPicker + 1], Time.time);
    25.         rend.material.SetColor("_Color", newColor);
    26.  
    27.         if (Time.time >= delay)
    28.         {
    29.             delay = Time.time + 2;
    30.             rainbowPicker ++;
    31.             if (rainbowPicker >= 6)
    32.                 rainbowPicker = 1;
    33.         }
    34.     }
     
  2. Cascho01

    Cascho01

    Joined:
    Mar 19, 2010
    Posts:
    1,347
    I´ve done a 2048x256 px rainbow in Photoshop for you:



    For scripting a colorlerp between these colors could work:

    Red(255,0,0)
    Magenta(255,0,255)
    Blue(0,0,255)
    Turqoise(0,255,255)
    Green(0,255,0)
    Yellow(255,255,0)
    Red
     
    Last edited: Sep 2, 2015
  3. tedthebug

    tedthebug

    Joined:
    May 6, 2015
    Posts:
    2,570
    If you want the screen to warp through in a pattern (like watching oil on water as it moves) then I have no idea. If you just want it to start from one end of the sample @Cascho01 did above, place it as a texture onto the object, scale & tile it how you want, then use a texture offset over time to scroll it. Make sure the texture has wrap set. This will make it scroll across, up, down at the speed you want & just continuously wrap. If this is what you want there is a good unity tutorial for the top down space shooter that shows how to make the background scroll using texture offsets.
     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Colours have three components or channels. You'll want to hold one channel at max, one channel at min, and move the other channel in between. Then do this across all three channels one after the other.
     
  5. L-Tyrosine

    L-Tyrosine

    Joined:
    Apr 27, 2011
    Posts:
    305
    Interpolating through RGB color space is a bad idea, as will mix brightness on the way. On the other hand, hue conservative transformation is handled easily in HSB color space.
    With the HSBColor class:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class HueShifter : MonoBehaviour
    5. {
    6.     public float Speed = 1;
    7.     private Renderer rend;
    8.  
    9.     void Start()
    10.     {
    11.         rend = GetComponent<Renderer>();
    12.     }
    13.  
    14.     void Update()
    15.     {
    16.         rend.material.SetColor("_Color", HSBColor.ToColor(new HSBColor( Mathf.PingPong(Time.time * Speed, 1), 1, 1)));
    17.     }
    18. }
    19.  
    Tweak transformation velocity with Speed public field. The second parameter on new HSBColor() is the Saturation. It's 1, using full saturation, but you can use something like 0.5f for colors closer to white.
     
    Last edited: Sep 2, 2015
  6. toasthat

    toasthat

    Joined:
    Sep 2, 2015
    Posts:
    2
    Thank you so so very much, this simple code achieves almost exactly what I want. I just got back from work and seeing the rainbow effect work makes me so happy :)

    I appreciate that you spent the time and effort to make that for me, but I already have a background texture I'm using.


    Anyway, thanks again L-Tyrosine, that code is perfect!
     
  7. Frieder_Mueller

    Frieder_Mueller

    Joined:
    Jan 6, 2018
    Posts:
    7
    Can you please help me? I want to apply this effect on the start color of a Trail Renderer but it says namespace Hsb color not found
     
    theordinarygreen likes this.
  8. theordinarygreen

    theordinarygreen

    Joined:
    Aug 2, 2017
    Posts:
    1
    Same.
     
  9. ElnuDev

    ElnuDev

    Joined:
    Sep 24, 2017
    Posts:
    298
    It's cyan, not turquoise.
     
  10. thebeastlyrenren

    thebeastlyrenren

    Joined:
    Apr 24, 2019
    Posts:
    1
    I am trying to get this to work in order to Hue Shift a 2D sprite by changing the Color property in the Sprite Renderer Component.
    This sprite is basically a background for my main menu and I am having trouble repurposing this code for my purpose, would you perhaps be able to point me in the right direction?
     
  11. FLIPAPANCAKE

    FLIPAPANCAKE

    Joined:
    Feb 27, 2020
    Posts:
    2
    try and make it into an animation to achieve this effect
     
  12. martip23

    martip23

    Joined:
    May 26, 2017
    Posts:
    1
    I didn't want to import a script, and keep it small, so I did it without using the HSBColor class, using RBGToHSV and HSVToRGB.

    Code (CSharp):
    1.  
    2. void Start()
    3.     {
    4.         // Initialize color, set material color using HSVToRGB.
    5.         Renderer.material.color = Color.HSVToRGB(.34f, .84f, .67f);
    6.     }
    7. void Update()
    8.     {
    9.         // Assign HSV values to float h, s & v. (Since material.color is stored in RGB)
    10.         float h, s, v;
    11.         Color.RGBToHSV(Renderer.material.color, out h, out s, out v);
    12.  
    13.         // Use HSV values to increase H in HSVToRGB. It looks like putting a value greater than 1 will round % 1 it
    14.         Renderer.material.color = Color.HSVToRGB(h + Time.deltaTime * .25f, s, v);
    15.     }
    16.  
     
  13. mystifluent

    mystifluent

    Joined:
    Mar 17, 2020
    Posts:
    2
    Before adding the script code,
    1. Make a new folder inside the main Assets folder of your game/project. Name the folder "Plugins".
    2. Inside that folder, create a new C# script named "HSBColor". Make sure that it is spelt correctly as the script that has the rainbow effect needs this.
    3. Insert the code below in the script:-
    4. Code (CSharp):
      1. using UnityEngine;
      2.  
      3. [System.Serializable]
      4. public struct HSBColor
      5. {
      6.     public float h;
      7.     public float s;
      8.     public float b;
      9.     public float a;
      10.  
      11.     public HSBColor(float h, float s, float b, float a)
      12.     {
      13.         this.h = h;
      14.         this.s = s;
      15.         this.b = b;
      16.         this.a = a;
      17.     }
      18.  
      19.     public HSBColor(float h, float s, float b)
      20.     {
      21.         this.h = h;
      22.         this.s = s;
      23.         this.b = b;
      24.         this.a = 1f;
      25.     }
      26.  
      27.     public HSBColor(Color col)
      28.     {
      29.         HSBColor temp = FromColor(col);
      30.         h = temp.h;
      31.         s = temp.s;
      32.         b = temp.b;
      33.         a = temp.a;
      34.     }
      35.  
      36.     public static HSBColor FromColor(Color color)
      37.     {
      38.         HSBColor ret = new HSBColor(0f, 0f, 0f, color.a);
      39.  
      40.         float r = color.r;
      41.         float g = color.g;
      42.         float b = color.b;
      43.  
      44.         float max = Mathf.Max(r, Mathf.Max(g, b));
      45.  
      46.         if (max <= 0)
      47.         {
      48.             return ret;
      49.         }
      50.  
      51.         float min = Mathf.Min(r, Mathf.Min(g, b));
      52.         float dif = max - min;
      53.  
      54.         if (max > min)
      55.         {
      56.             if (g == max)
      57.             {
      58.                 ret.h = (b - r) / dif * 60f + 120f;
      59.             }
      60.             else if (b == max)
      61.             {
      62.                 ret.h = (r - g) / dif * 60f + 240f;
      63.             }
      64.             else if (b > g)
      65.             {
      66.                 ret.h = (g - b) / dif * 60f + 360f;
      67.             }
      68.             else
      69.             {
      70.                 ret.h = (g - b) / dif * 60f;
      71.             }
      72.             if (ret.h < 0)
      73.             {
      74.                 ret.h = ret.h + 360f;
      75.             }
      76.         }
      77.         else
      78.         {
      79.             ret.h = 0;
      80.         }
      81.  
      82.         ret.h *= 1f / 360f;
      83.         ret.s = (dif / max) * 1f;
      84.         ret.b = max;
      85.  
      86.         return ret;
      87.     }
      88.  
      89.     public static Color ToColor(HSBColor hsbColor)
      90.     {
      91.         float r = hsbColor.b;
      92.         float g = hsbColor.b;
      93.         float b = hsbColor.b;
      94.         if (hsbColor.s != 0)
      95.         {
      96.             float max = hsbColor.b;
      97.             float dif = hsbColor.b * hsbColor.s;
      98.             float min = hsbColor.b - dif;
      99.  
      100.             float h = hsbColor.h * 360f;
      101.  
      102.             if (h < 60f)
      103.             {
      104.                 r = max;
      105.                 g = h * dif / 60f + min;
      106.                 b = min;
      107.             }
      108.             else if (h < 120f)
      109.             {
      110.                 r = -(h - 120f) * dif / 60f + min;
      111.                 g = max;
      112.                 b = min;
      113.             }
      114.             else if (h < 180f)
      115.             {
      116.                 r = min;
      117.                 g = max;
      118.                 b = (h - 120f) * dif / 60f + min;
      119.             }
      120.             else if (h < 240f)
      121.             {
      122.                 r = min;
      123.                 g = -(h - 240f) * dif / 60f + min;
      124.                 b = max;
      125.             }
      126.             else if (h < 300f)
      127.             {
      128.                 r = (h - 240f) * dif / 60f + min;
      129.                 g = min;
      130.                 b = max;
      131.             }
      132.             else if (h <= 360f)
      133.             {
      134.                 r = max;
      135.                 g = min;
      136.                 b = -(h - 360f) * dif / 60 + min;
      137.             }
      138.             else
      139.             {
      140.                 r = 0;
      141.                 g = 0;
      142.                 b = 0;
      143.             }
      144.         }
      145.  
      146.         return new Color(Mathf.Clamp01(r), Mathf.Clamp01(g), Mathf.Clamp01(b), hsbColor.a);
      147.     }
      148.  
      149.     public Color ToColor()
      150.     {
      151.         return ToColor(this);
      152.     }
      153.  
      154.     public override string ToString()
      155.     {
      156.         return "H:" + h + " S:" + s + " B:" + b;
      157.     }
      158.  
      159.     public static HSBColor Lerp(HSBColor a, HSBColor b, float t)
      160.     {
      161.         float h, s;
      162.  
      163.         //check special case black (color.b==0): interpolate neither hue nor saturation!
      164.         //check special case grey (color.s==0): don't interpolate hue!
      165.         if (a.b == 0)
      166.         {
      167.             h = b.h;
      168.             s = b.s;
      169.         }
      170.         else if (b.b == 0)
      171.         {
      172.             h = a.h;
      173.             s = a.s;
      174.         }
      175.         else
      176.         {
      177.             if (a.s == 0)
      178.             {
      179.                 h = b.h;
      180.             }
      181.             else if (b.s == 0)
      182.             {
      183.                 h = a.h;
      184.             }
      185.             else
      186.             {
      187.                 // works around bug with LerpAngle
      188.                 float angle = Mathf.LerpAngle(a.h * 360f, b.h * 360f, t);
      189.                 while (angle < 0f)
      190.                     angle += 360f;
      191.                 while (angle > 360f)
      192.                     angle -= 360f;
      193.                 h = angle / 360f;
      194.             }
      195.             s = Mathf.Lerp(a.s, b.s, t);
      196.         }
      197.         return new HSBColor(h, s, Mathf.Lerp(a.b, b.b, t), Mathf.Lerp(a.a, b.a, t));
      198.     }
      199.  
      200.     public static void Test()
      201.     {
      202.         HSBColor color;
      203.  
      204.         color = new HSBColor(Color.red);
      205.         Debug.Log("red: " + color);
      206.  
      207.         color = new HSBColor(Color.green);
      208.         Debug.Log("green: " + color);
      209.  
      210.         color = new HSBColor(Color.blue);
      211.         Debug.Log("blue: " + color);
      212.  
      213.         color = new HSBColor(Color.grey);
      214.         Debug.Log("grey: " + color);
      215.  
      216.         color = new HSBColor(Color.white);
      217.         Debug.Log("white: " + color);
      218.  
      219.         color = new HSBColor(new Color(0.4f, 1f, 0.84f, 1f));
      220.         Debug.Log("0.4, 1f, 0.84: " + color);
      221.  
      222.         Debug.Log("164,82,84   .... 0.643137f, 0.321568f, 0.329411f  :" + ToColor(new HSBColor(new Color(0.643137f, 0.321568f, 0.329411f))));
      223.     }
      224. }
    5. After you paste the above code into the HSBColor.cs script, you can insert the rainbow effect code and it will not show any errors. Make sure your renderer is white too for the effect to work!
    If it still shows errors, please reply.
     
    AdamEF and stevepdp like this.