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

Method Extension doesn't work properly for me

Discussion in 'Scripting' started by MaZy, Aug 16, 2014.

  1. MaZy

    MaZy

    Joined:
    Jun 29, 2012
    Posts:
    100
    Hello. I am writing my small GUI System.
    But I don't get this

    Code (CSharp):
    1.        
    2.         Rect CloseButtonRect = new Rect(0,10f,GetBaseDimension().width - 50f,50f);
    3.         CloseButtonRect.Center(GetBaseDimension());
    4.         Debug.Log(CloseButtonRect);
    5.  

    Code (CSharp):
    1. public static class GUIBaseRectExtension {
    2.  
    3.     public static Rect Center(this Rect r, Rect relativeDimension) {
    4.         r.x = relativeDimension.width / 2f - r.width / 2f;
    5.         r.y = relativeDimension.height / 2f - r.height / 2f;
    6.      
    7.         Debug.Log(r);
    8.      
    9.         return r;
    10.     }
    11. }
    so the Debug shows.
    (x:25.00, y:125.00, width:150.00, height:50.00) = r
    (x:0.00, y:10.00, width:150.00, height:50.00) = ClosButtonRect

    Why "r" is changed but not CloseButtonRect?

    Here this is working why? Why not r.x and r.y?
    http://unity3d.com/learn/tutorials/modules/intermediate/scripting/extension-methods
    Code (CSharp):
    1. public static void ResetTransformation(this Transform trans)
    2.     {
    3.         trans.position = Vector3.zero;
    4.         trans.localRotation = Quaternion.identity;
    5.         trans.localScale = new Vector3(1, 1, 1);
    6.     }
     
  2. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,716
    Code (CSharp):
    1. CloseButtonRect = CloseButtonRect.Center(GetBaseDimension());
     
  3. landon912

    landon912

    Joined:
    Nov 8, 2011
    Posts:
    1,579
    This is due to Rect being a strut. Struts are stored on the stack, and passed by value not reference. So when you call the extension, r is created on the stack and then assigned the value from the field passed into the parameter, instead of the reference being copied as if the parameter was a class.

    Stack vs Heap

    You could and should use the method shown above, but in theory you could tell the program to explicitly pass the struct by reference using the ref keyword, however the above is vastly the standard and the correct way to handle this situation.
     
  4. MaZy

    MaZy

    Joined:
    Jun 29, 2012
    Posts:
    100
    Thank you I get it.

    @LightStriker, yea I know this. Was using like that. That is the reason why I leave the "return" there. But I thought there is a way to avoid it (without ref).

    But thanks anyway.

    Another question. Is it possible to lock OnGUI for child classes? I wrote a Draw() method and I want to allow other classes only the Draw(). Thats because the main base class uses this:

    Code (CSharp):
    1. GUI.BeginGroup()
    2. Draw()
    3. GUI.EndGroup()
    With this technique I can make sliding GUIs. But if the other childs classes uses OnGUI so it won't work. So I would like to have a compiler.

    Of Course if I am using myself no problem. I will remember but not if there are some other people.