Search Unity

How to use System.Func<>

Discussion in 'Scripting' started by keenanwoodall, Mar 30, 2015.

  1. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    I'm using the CoherentNoise library and one of the classes constructors requires "System.Func<int, int, int, float>" I have no idea what to pass it. Intelisense says this:

    Code (csharp):
    1.  
    2. public  VoronoiCells(
    3.      int seed
    4.      System.Func<int, int, int, float> cellValueSource
    5. )
    6. Parameter
    7. cellValueSource: Function that returns cell's value
    8.  
    9. Delegate Info
    10. TResult Func (T1 arg, T2 arg2, T3 arg3)
    11.  
    12. Summary
    13. Create a new Voronoi diagram using seed. Control points will be obtained
    14. using random displacement seed by supplied value
     
  2. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    System.Func and System.Action are C#'s delegate classes!

    Basically, it's asking for a delegate method as an argument, specifically one that takes three integers and returns a float.

    There's lots of ways to write these, but the best is using lambda expressions:
    Code (CSharp):
    1. VeronicCells(1000, (x,y,x) => {
    2.  
    3.     //do something with x y z and return a float.
    4.  
    5.     return (float)(x * 2 + y * 5 * z - 1000);
    6.  
    7. });
    Check it out:
    http://www.dotnetperls.com/lambda <- Check it out.

    That said I'm imagining this library probably already has a number of cellValueSource methods defined somewhere, and is probably expecting you to use one of them.
     
  3. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    Ok, I kinda understand. But I've tried to implement the lambda and get an error. Here's my code
    Code (csharp):
    1.  
    2. [System.Serializable]
    3.         public class Function
    4.         {
    5.             //Public
    6.             [Range(1, 4096)]
    7.             public int width = 16;
    8.             [Range(1, 4096)]
    9.             public int height = 16;
    10.  
    11.             public float x;
    12.             public float y;
    13.             public float z;
    14.  
    15.             public float gain = 1f;
    16.             public float bias = 1f;
    17.  
    18.             public Texture2D ramp;
    19.  
    20.             public UnityEngine.Texture GetTexture()
    21.             {
    22.                 CoherentNoise.Generation.Function function = new CoherentNoise.Generation.Function((x, y, z) => {return x + y + z;});
    23.  
    24.                 Generator gainFunction = function.Gain(gain);
    25.                 Generator biasFunction = gainFunction.Bias(bias);
    26.  
    27.                 if(ramp != null)
    28.                     return TextureMaker.RampTexture(width, height, biasFunction, ramp);
    29.                 else
    30.                     return new UnityEngine.Texture();
    31.             }
    32.         }
    33.  
    Here's my error

    IndexOutOfRangeException: Array index is out of range.
    CoherentNoise.Texturing.TextureMaker+<>c__DisplayClass7.<RampTexture>b__6 (Single x, Single y)
    CoherentNoise.Texturing.TextureMaker.Make (Int32 width, Int32 height, System.Func`3 colorFunc, TextureFormat format)
    CoherentNoise.Texturing.TextureMaker.RampTexture (Int32 width, Int32 height, CoherentNoise.Generator noise, UnityEngine.Texture2D ramp)
    Procedural+Texture+Function.GetTexture () (at Assets/Code/Framework/Procedural.cs:458)
    ProceduralTexture.Update () (at Assets/Code/ProceduralTexture.cs:40)