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

Resolved How do i call a MonoBehaviour method from a static non-MonoBehaviour?

Discussion in 'Scripting' started by gjaccieczo, Sep 7, 2021.

  1. gjaccieczo

    gjaccieczo

    Joined:
    Jun 30, 2021
    Posts:
    306
    I have two scripts: one that doesn't inherit from anything (ANonMonoScript) and the other that inherits from MonoBehaviour (AMonoBehaviour).
    Non-Monobehaviour:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ANonMonoScript
    6. {
    7.     public static void AMethod()
    8.     {
    9.         // irrelevant code
    10.  
    11.         // <=   here i want to call a method from the AMonoBehaviour MonoBehaviour script.
    12. }
    MonoBehaviour:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class AMonoBehaviour : MonoBehaviour
    7. {
    8.     public Button button;
    9.     public Sprite ASprite;
    10.  
    11.     void Awake()
    12.     {
    13.  
    14.     }
    15.     void Start()
    16.     {
    17.    
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.    
    24.     }
    25.  
    26.     public void AMethodToCall()
    27.     {
    28.         button.image.sprite = ASprite;
    29.     }
    30. }
    The MonoBehaviour is attached to the Button UI GameObject. I'm trying to change the Target Graphic of the UI button to the image that i have attached to the ASprite in the Inspector when AMethodToCall() is called from the AMethod() of the ANonMonoScript.

    However, i don't know how to call the MonoBehaviour method from the static non-Monobehaviour.

    Thank you for your answers!
     
    Last edited: Sep 8, 2021
  2. PizzaPie

    PizzaPie

    Joined:
    Oct 11, 2015
    Posts:
    107
    It is not clear from where you call the static method or what is the point of the design but if you want to use instance members anywhere outside of the class itself (or classes that inherit from it) you need a reference.


    Code (CSharp):
    1. public static AMethod(AMonoBehaviour aMonoBehaviour)
    2. {
    3.         aMonoBehaviour.AMethodToCall();
    4. }
     
    Bunny83 and gjaccieczo like this.
  3. gjaccieczo

    gjaccieczo

    Joined:
    Jun 30, 2021
    Posts:
    306
    Thank you for your answer, @PizzaPie! Seems that i have made quite a typo in my original post. I'm trying to call a MonoBehaviour method from a static non-MonoBehaviour, not to call a static non-MonoBehaviour from a MonoBehaviour o_O. Sorry, my bad, corrected the wording in the post! The question still stands :).
     
    Last edited: Sep 7, 2021
  4. PizzaPie

    PizzaPie

    Joined:
    Oct 11, 2015
    Posts:
    107
    Doesn't really matter, you ll always need a reference to the target object, how to obtain that reference depends on the overall structure of your system. I can't really provide any insight given the lack of info on the intended usecase.
     
    gjaccieczo likes this.
  5. gjaccieczo

    gjaccieczo

    Joined:
    Jun 30, 2021
    Posts:
    306
    Regardless, thank you for your help! There isn't much to the structure in this particular case other than script A and script B, with script B (the MonoBehaviour) being attached to the Button GameObject.
     
  6. gjaccieczo

    gjaccieczo

    Joined:
    Jun 30, 2021
    Posts:
    306
    Providing some extra details that might help (just realized what @PizzaPie meant when they said "the overall structure of your system"):
    The MonoBehaviour method, that i'm trying to call from a static non-MonoBehaviour method is in a script that is attached to a Button UI Object, which is a child object of Canvas UI Object. The ASprite is a PNG image that i have attached via Inspector.
     
  7. gjaccieczo

    gjaccieczo

    Joined:
    Jun 30, 2021
    Posts:
    306
    Resolved the issue by simply:
    • creating a custom tag for the Button GameObject (AButtonTag).
    • creating a reference of the script type that i'm trying to access.
    • finding the GameObject by tag and using GetComponent to access the script in question.
    Non-Monobehaviour:

    Code (CSharp):
    1.     using System.Collections;
    2.     using System.Collections.Generic;
    3.     using UnityEngine;
    4.  
    5.     public static AMonoBehaviour aMono;
    6.  
    7.     public static class ANonMonoScript
    8.     {
    9.         public static void AMethod()
    10.         {
    11.        
    12.             aMono = GameObject.FindGameObjectsWithTag("AButtonTag")[0].GetComponent<AMonoBehaviour>();
    13.          
    14.             // irrelevant code
    15.  
    16.             aMono.AMethodToCall(); // <=   here i  call a method from the AMonoBehaviour MonoBehaviour script
    17.         }
    18.  
    MonoBehaviour:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class AMonoBehaviour : MonoBehaviour
    7. {
    8.     public Button button;
    9.     public Sprite ASprite;
    10.  
    11.     void Awake()
    12.     {
    13.  
    14.     }
    15.     void Start()
    16.     {
    17.  
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.  
    24.     }
    25.  
    26.     public void AMethodToCall()
    27.     {
    28.         button.image.sprite = ASprite;
    29.     }
    30. }
    I've also found a question, that is similar to mine (which essentially resolved my problem), might be helpful to some:
    https://forum.unity.com/threads/get-reference-to-gameobject-from-non-monobehaviour-class.498115/
     
    wicke likes this.
  8. ghostcameron

    ghostcameron

    Joined:
    Oct 17, 2017
    Posts:
    1
    I don't understand why you said you need a reference as you can utilize most of the methods statically. Not the most useful example as I am calling print but it could be more useful with a spawn item command where you need to instantiate.


    Code (CSharp):
    1. public class Commands
    2. {
    3.  
    4.     public static void EnableRagdoll(GameObject gObj) {
    5.         MonoBehaviour.print("Print");
    6.         foreach(var child in gObj.GetComponentsInChildren<Rigidbody>()){
    7.             child.isKinematic = false;
    8.         }
    9.     }
    10. }
    11. // Usage
    12. Commands.EnableRagdoll(gameObject);
     
    gjaccieczo likes this.
  9. gjaccieczo

    gjaccieczo

    Joined:
    Jun 30, 2021
    Posts:
    306
    This is true, but the static keyword is best used with things that you only need 1 of. Regardless, thank you for your input!