Search Unity

How to make GUI Button activate script (JS or C#)

Discussion in 'Scripting' started by Exnihilon, Apr 21, 2014.

  1. Exnihilon

    Exnihilon

    Joined:
    Mar 2, 2014
    Posts:
    158
    Hello to all. I really need your help to make my GUI.Button start a script JS (or C#) attached to a GameObject. Here is what I have in my application. A JS script "doRotate.js", that does a rotation on a GameObject:

    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4.     private var doRotation = false;
    5.      
    6.     function Update()
    7.     {
    8.         if (doRotation)
    9.         {
    10.             transform.Rotate(new Vector3(0, 50, 0) * Time.deltaTime);
    11.         }
    12.     }
    13.  
    I also have a JS script that renders some buttons. I want button 2, once pressed to call (run) the "doRotate.js" script.
    This is what I've tried to do, but I get this error "Error BCE0020: An instance of type 'doRotate' is required to access non static member 'doRotation'. (BCE0020)".

    What have I done wrong? I've trying for the hole day, without success. Can somone, please help me out? Here is the code on the GUI.button:

    Code (csharp):
    1.  
    2.  
    3.     var native_width :  float = 480;
    4.     var native_height : float = 320;
    5.     var addImage : Texture2D;
    6.            
    7.     var btnTexture1 : Texture;
    8.     var btnTexture2 : Texture;
    9.      
    10.    
    11.     function OnGUI ()
    12.     {
    13.     var rx : float = Screen.width / native_width;
    14.     var ry : float = Screen.height / native_height;
    15.     GUI.matrix = Matrix4x4.TRS (Vector3(0, 0, 0), Quaternion.identity, Vector3 (rx, ry, 1));
    16.          
    17.     GUI.Box( Rect(20, 200, 429, 129) ,addImage, "");
    18.       if (!btnTexture1) {
    19.             Debug.LogError("Please assign a texture on the inspector");
    20.             return;
    21.             }
    22.            
    23.             GUI.Button(Rect(54, 222, 52, 35), btnTexture1);
    24.    
    25.     if (!btnTexture2) {
    26.             Debug.LogError("Please assign a texture on the inspector");
    27.             return;
    28.             }
    29.            
    30.             if(GUI.Button(Rect(118, 222, 52, 35), btnTexture2));
    31.                          
    32.                 var runScript : GameObject[] =
    33.                 GameObject.FindGameObjectsWithTag("markerObject");
    34.                 for(var doRotation : GameObject in runScript) {
    35.                 var script : doRotate = doRotation.GetComponent(doRotate);
    36.                 if(script)
    37.                 doRotate.doRotation(); //Error BCE0020: An instance of type 'doRotate' is required to access non static member 'doRotation'. (BCE0020)
    38.             }
    39.  
    40.  
    Thank you all in advance. Please, someone respond to a newbie in Unity.
     
  2. Beennn

    Beennn

    Joined:
    Sep 11, 2010
    Posts:
    373
    You're getting the error because
    Code (csharp):
    1.  doRotate.doRotation();
    is looking for a static method called doRotation in class doRotate, which doesn't exist.

    Replace your doRotate script with:
    Code (csharp):
    1.  
    2. static function doRotation()
    3. {
    4.     transform.Rotate(new Vector3(0, 50, 0) * Time.deltaTime);
    5. }
    6.  
    Alternatively, you could replace:
    Code (csharp):
    1.  doRotate.doRotation();
    With:
    Code (csharp):
    1.  script.doRotation()
    And then in your doRotate script:
    Code (csharp):
    1.  
    2. function doRotation()
    3. {
    4.     transform.Rotate(new Vector3(0, 50, 0) * Time.deltaTime);
    5. }
    6.  
     
  3. Exnihilon

    Exnihilon

    Joined:
    Mar 2, 2014
    Posts:
    158
    Hello @Beennn, and thank you for your suggestion. Unfortunately none of them worked on compilation. Let me explain.

    I've followed your first suggestion to replace the doRotate script with the static function. If I keep the " private var doRotation = false;" in script I get this error:

    Error BCE0089: Type 'doRotate' already has a definition for 'doRotation'. (BCE0089)

    If I quote the " private var doRotation = false;" I get the following erron on compilation:

    Error BCE0020: An instance of type 'UnityEngine.Component' is required to access non static member 'transform'. (BCE0020)

    Following your alternative suggestion, by replacing the "doRotate.doRotation(); by "script.doRotation(); I am getting no action at all when the GUI.Button is clicked!

    I believe you are to the point of the initial problem of "instance of type...", but I can figure out what else is wrong and I don't get the rotation on button clicked.

    Do you have anything else to suggest? Waiting for your responce and thank you in advance
     
  4. Beennn

    Beennn

    Joined:
    Sep 11, 2010
    Posts:
    373
    Your script never toggled
    Code (csharp):
    1. doRotation
    , therefore when I said to replace your doRotate script with the snippet I posted, I mean't the whole script, that's why you were getting the error.

    Your second issue regarding nothing happening, I didn't notice you were calling it from a button press, that's my bad.

    Put:
    Code (csharp):
    1. #pragma strict
    2.  
    3.     public var doRotation = false;
    4.  
    5.     function Update()
    6.  
    7.     {
    8.  
    9.         if (doRotation)
    10.  
    11.         {
    12.  
    13.             transform.Rotate(new Vector3(0, 50, 0) * Time.deltaTime);
    14.  
    15.         }
    16.  
    17.     }
    in your doRotate script, and change:
    Code (csharp):
    1. doRotate.doRotation();
    To:
    Code (csharp):
    1. script.doRotation = true;
    Your original solution, if you wanted to keep to your original thinking, could instead have a static method in doRotate called doRotation, which toggled the local variable so your doRotatation script would be:
    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4.     private static var rotate = false;
    5.  
    6.     function Update()
    7.     {
    8.  
    9.         if (rotate)
    10.  
    11.         {
    12.  
    13.             transform.Rotate(new Vector3(0, 50, 0) * Time.deltaTime);
    14.  
    15.         }
    16.  
    17.     }
    18.    
    19.     static function doRotation () {
    20.         rotate = !rotate;
    21.     }
    22.  
     
    Last edited: Apr 21, 2014
  5. Exnihilon

    Exnihilon

    Joined:
    Mar 2, 2014
    Posts:
    158
    Hi Beennn, thank you a lot for your reply. I have followed your edited snippet and I get this error in the compilation:

    "Error BCE0049: Expression 'script.doRotation' cannot be assigned to. (BCE0049)"

    See the updated code that renders the GUI.Button:

    Code (csharp):
    1.  
    2.  
    3. #pragma strict
    4.  
    5.     var native_width :  float = 480;
    6.     var native_height : float = 320;
    7.     var ctrlImage : Texture2D;
    8.            
    9.     var btnTexture1 : Texture;
    10.     var btnTexture2 : Texture;
    11.     var btnTexture3 : Texture;
    12.     var btnTexture4 : Texture;
    13.     var btnTexture5 : Texture;
    14.     var btnTexture6 : Texture;
    15.     var btnTexture7 : Texture;
    16.  
    17.     var isBoxShowing : boolean;
    18.     var script : GameObject;
    19.  
    20.     function OnGUI ()
    21.     {
    22.     //set up scaling
    23.     var rx : float = Screen.width / native_width;
    24.     var ry : float = Screen.height / native_height;
    25.     GUI.matrix = Matrix4x4.TRS (Vector3(0, 0, 0), Quaternion.identity, Vector3 (rx, ry, 1));
    26.      
    27.     //now create your GUI normally, as if you were in your native resolution
    28.     //The GUI.matrix will scale everything automatically.
    29.      
    30.     GUI.Box( Rect(20, 200, 429, 129) ,ctrlImage, "");
    31.       if (!btnTexture1) {
    32.             Debug.LogError("Please assign a texture on the inspector");
    33.             return;
    34.             }
    35.            
    36.             GUI.Button(Rect(54, 222, 52, 35), btnTexture1);
    37.    
    38.     if (!btnTexture2) {
    39.             Debug.LogError("Please assign a texture on the inspector");
    40.             return;
    41.             }
    42.            
    43.             if(GUI.Button(Rect(118, 222, 52, 35), btnTexture2));
    44.          
    45.                    
    46.                 var runScript : GameObject[] =
    47.  
    48.                 GameObject.FindGameObjectsWithTag("markerObject");
    49.  
    50.                 for(var doRotation : GameObject in runScript) {
    51.  
    52.                 var script : doRotate = doRotation.GetComponent(doRotate);
    53.  
    54.                 if(script)
    55.  
    56.                script.doRotation = true; //Error BCE0049: Expression 'script.doRotation' cannot be assigned to. (BCE0049)
    57.  
    58.  
    And here is the updated code of the "doRotate.js" script, that gives another error " Error BCE0049: Expression 'doRotate.doRotation' cannot be assigned to. (BCE0049)".

    Code (csharp):
    1.  
    2.  
    3.  #pragma strict
    4.      
    5.         private var rotate = false;
    6.      
    7.         function Update()
    8.         {
    9.      
    10.             if (rotate)
    11.      
    12.             {
    13.      
    14.                 transform.Rotate(new Vector3(0, 50, 0) * Time.deltaTime);
    15.      
    16.             }
    17.      
    18.         }
    19.        
    20.         static function doRotation () {
    21.             doRotation = !doRotation;
    22.         }
    23.  
    24.  

    Well, what might be the issue here and it does not compiles and runs? Any suggestions? What is missing?
     
  6. Beennn

    Beennn

    Joined:
    Sep 11, 2010
    Posts:
    373
    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4.  
    5.  
    6.     var native_width :  float = 480;
    7.  
    8.     var native_height : float = 320;
    9.  
    10.     var ctrlImage : Texture2D;
    11.  
    12.            
    13.  
    14.     var btnTexture1 : Texture;
    15.  
    16.     var btnTexture2 : Texture;
    17.  
    18.     var btnTexture3 : Texture;
    19.  
    20.     var btnTexture4 : Texture;
    21.  
    22.     var btnTexture5 : Texture;
    23.  
    24.     var btnTexture6 : Texture;
    25.  
    26.     var btnTexture7 : Texture;
    27.  
    28.  
    29.  
    30.     var isBoxShowing : boolean;
    31.  
    32.     var script : GameObject;
    33.  
    34.  
    35.  
    36.     function OnGUI ()
    37.  
    38.     {
    39.  
    40.     //set up scaling
    41.  
    42.     var rx : float = Screen.width / native_width;
    43.  
    44.     var ry : float = Screen.height / native_height;
    45.  
    46.     GUI.matrix = Matrix4x4.TRS (Vector3(0, 0, 0), Quaternion.identity, Vector3 (rx, ry, 1));
    47.  
    48.      
    49.  
    50.     //now create your GUI normally, as if you were in your native resolution
    51.  
    52.     //The GUI.matrix will scale everything automatically.
    53.  
    54.      
    55.  
    56.     GUI.Box( Rect(20, 200, 429, 129) ,ctrlImage, "");
    57.  
    58.       if (!btnTexture1) {
    59.  
    60.             Debug.LogError("Please assign a texture on the inspector");
    61.  
    62.             return;
    63.  
    64.             }
    65.  
    66.            
    67.  
    68.             GUI.Button(Rect(54, 222, 52, 35), btnTexture1);
    69.  
    70.    
    71.  
    72.     if (!btnTexture2) {
    73.  
    74.             Debug.LogError("Please assign a texture on the inspector");
    75.  
    76.             return;
    77.  
    78.             }
    79.  
    80.            
    81.  
    82.             if(GUI.Button(Rect(118, 222, 52, 35), btnTexture2));
    83.  
    84.          
    85.  
    86.                    
    87.  
    88.                 var runScript : GameObject[] =
    89.  
    90.  
    91.  
    92.                 GameObject.FindGameObjectsWithTag("markerObject");
    93.  
    94.  
    95.  
    96.                 for(var doRotation : GameObject in runScript) {
    97.  
    98.  
    99.  
    100.                 var script : doRotate = doRotation.GetComponent(doRotate);
    101.  
    102.  
    103.  
    104.                 if(script)
    105.  
    106.  
    107.  
    108.                doRotate.doRotation(); //Error BCE0049: Expression 'script.doRotation' cannot be assigned to. (BCE0049)
    109.  
    Code (csharp):
    1.  
    2.  #pragma strict
    3.  
    4.         private static var rotate = false;
    5.  
    6.         function Update()
    7.  
    8.         {
    9.  
    10.             if (rotate)
    11.  
    12.             {
    13.                 transform.Rotate(new Vector3(0, 50, 0) * Time.deltaTime);
    14.  
    15.             }
    16.  
    17.         }
    18.         static function doRotation () {
    19.  
    20.             rotate = !rotate;
    21.  
    22.         }
    23.  
     
    Last edited: Apr 21, 2014
  7. Exnihilon

    Exnihilon

    Joined:
    Mar 2, 2014
    Posts:
    158
    Beennn, I don't know where this little demon was hiding in this code, but now it compiles, ok. The problem is it does not functions as it should on pressing the GUI.Button. It does nothing at all. What is more, the "doRotate.js" is functional only if the "private static var rotate" is chanced from default "false" to "true". But this is the case. I need that variable to accessed and chanced to "true" only on pressing that GUI.Button.
    Is there a solution here, or it is impossible to make those scripts function? Sorry for bothering you, but you are the only one that is interested in helping me.
     
  8. Beennn

    Beennn

    Joined:
    Sep 11, 2010
    Posts:
    373
    I've just gone through it quickly in Unity, your button was a stub:
    Code (csharp):
    1. if(GUI.Button(Rect(118, 222, 52, 35), btnTexture2));
    This mean't your loop was executing every frame. I suggest reading: https://docs.unity3d.com/Documentation/Components/GUIScriptingGuide.html

    Here's it working:
    Code (csharp):
    1. #pragma strict
    2.  
    3. var native_width :  float = 480;
    4.  
    5. var native_height : float = 320;
    6.  
    7. var ctrlImage : Texture2D;
    8.  
    9. var btnTexture1 : Texture;
    10.  
    11. var btnTexture2 : Texture;
    12.  
    13. var btnTexture3 : Texture;
    14.  
    15. var btnTexture4 : Texture;
    16.  
    17. var btnTexture5 : Texture;
    18.  
    19. var btnTexture6 : Texture;
    20.  
    21. var btnTexture7 : Texture;
    22.  
    23. var isBoxShowing : boolean;
    24.  
    25. var script : GameObject;
    26.  
    27. function OnGUI ()
    28. {
    29.  
    30.     //set up scaling
    31.     var rx : float = Screen.width / native_width;
    32.     var ry : float = Screen.height / native_height;
    33.  
    34.     GUI.matrix = Matrix4x4.TRS (Vector3(0, 0, 0), Quaternion.identity, Vector3 (rx, ry, 1));
    35.  
    36.     //now create your GUI normally, as if you were in your native resolution
    37.  
    38.     //The GUI.matrix will scale everything automatically.
    39.  
    40.     GUI.Box( Rect(20, 200, 429, 129) ,ctrlImage, "");
    41.  
    42.     if (!btnTexture1)
    43.     {
    44.         Debug.LogError("Please assign a texture on the inspector");
    45.         return;
    46.     }
    47.  
    48.     GUI.Button(Rect(54, 222, 52, 35), btnTexture1);
    49.  
    50.     if (!btnTexture2)
    51.     {
    52.         Debug.LogError("Please assign a texture on the inspector");
    53.         return;
    54.     }
    55.  
    56.  
    57.     if(GUI.Button(Rect(118, 222, 52, 35), btnTexture2)) {
    58.  
    59.         var runScript : GameObject[] = GameObject.FindGameObjectsWithTag("markerObject");
    60.  
    61.         for(var doRotation : GameObject in runScript) {
    62.  
    63.             var script : doRotate = doRotation.GetComponent(doRotate);
    64.  
    65.             if(script) {
    66.                 doRotate.doRotation();
    67.             }
    68.  
    69.         }
    70.    
    71.     }
    72.        
    73. }
    74.  
    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. private static var rotate = false;
    5.  
    6. function Update()
    7. {
    8.  
    9.     if (rotate)
    10.     {
    11.         transform.Rotate(new Vector3(0, 50, 0) * Time.deltaTime);
    12.     }
    13.  
    14. }
    15.  
    16. static function doRotation () {
    17.  
    18.     rotate = !rotate;
    19.  
    20. }
    21.  
     
  9. Exnihilon

    Exnihilon

    Joined:
    Mar 2, 2014
    Posts:
    158
    Thank you very much Beennn, for you time, efford and your valuable suggestions. You have found the solution on this problematic coding.
    It has being bugging me for 3 days now. I have never ever, heard before about a button being a "stub" and what problem is causing to a running code.

    I am a newbie in coding and in Unity3d, and there is a lot to learn. I am currently developing my post-graduation application for Android and AR.
    So any help would be very much welcomed. May I contact you through pm, if I got stuck again somehow? It seems you are very skillful to UnityScripting.

    I have some other scripts I need to access them and their vars, through functional GUI.Buttons. Those scripts are on C# and JS.

    Is there a tutorial, a step by step guide, or even an example code to follow up?


    How can I mark this answer as the correct one, so you can get reputation? Thank you again!