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

Question Using a referenced parameter

Discussion in 'Scripting' started by Daviiid, Jan 4, 2023.

  1. Daviiid

    Daviiid

    Joined:
    Oct 9, 2015
    Posts:
    50
    My code:
    Code (CSharp):
    1.     MainInventory mainInventory;
    2.  
    3.     void Start()
    4.     {
    5.         mainInventory = FindObjectOfType<MainInventory>();
    6.     }
    7.  
    8.     public void OnEnableUI()
    9.     {
    10.         int i = mainInventory.GetCorpseCount();
    11.         i = mainInventory.CorpseQty;
    12.         CorpseCount.text = i.ToString();
    13.     }
    Simple code where I get the reference of an integer from another script.
    I've tried to use int i = mainInventory.GetCorpseCount(); and i = mainInventory.CorpseQty; separately.
    Yet non of them work. The parameter is public and so is the method that I'm calling to get the same parameter.

    If I Serialize the field mainInventory(plus attach the object) and remove the start method. Everything works.

    I only have 1 object with a script like that. So it can't be that the findObjectOfType would give me multiple results. And I'm using the start method: mainInventory = FindObjectOfType<MainInventory>();
    In other scripts and they are working fine.

    Example Script:
    Code (CSharp):
    1. MainInventory mainInventory;
    2.  
    3.     void Start()
    4.     {
    5.         mainInventory = FindObjectOfType<MainInventory>();
    6.     }
    7. public void FertilizingFill()
    8.     {
    9.         if (mainInventory.FertilizerQty > 0)
    10.         {
    11.             FertilizingAnim.SetActive(true);
    12.             animDone = true;
    13.             mainInventory.DecreaseFertilizerQty();
    14.         }
    15.         else audSrc.PlayOneShot(NASound);
    16.     }
    I might be using a different variable there, but both are public and in the same script.

    Is it working because I'm only trying to compare it in the second script?
    I don't understand the issue. I'm not even sure where to exactly look for answers in the manual.
     
  2. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    717
    What does "doesn't work" mean? Is the number wrong? Is it always a zero? Does it throw an exception?
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Start is pretty late in the lifecycle to be asking for stuff. What if something else calls your public methods BEFORE Start() runs? BOOM

    Here is some timing diagram help:

    https://docs.unity3d.com/Manual/ExecutionOrder.html

    Here is an abbreviated and better-annotated version of the above:

    https://forum.unity.com/threads/a-c...ution-order-of-unity-event-functions.1381647/

    I'm guessing you're seeing a nullref:

    How to fix a NullReferenceException error

    https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

    Three steps to success:
    - Identify what is null <-- any other action taken before this step is WASTED TIME
    - Identify why it is null
    - Fix that
     
    Daviiid likes this.
  4. Daviiid

    Daviiid

    Joined:
    Oct 9, 2015
    Posts:
    50
    Thank you Kurt
    Code (CSharp):
    1. ComposterUI.SetActive(true);
    2.         ComposterUI.GetComponent<CompostUISetting>().OnEnableUI();
    First I'm setting the gameObject active. Then I'm calling a method in that gameObjects script. It seems that the Start() method on that gameObject is run later than the method I'm calling on it. Since that gameObject is turned off on default.

    I've tried Awake() after reading your links and it had no issues.

    Chemicalcrux: There was a null reference where I was trying to fill [int i =]. Sorry It was late at night.
     
  5. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Start runs right before the first call to Update(). So it will not run in-between your two lines of code.
    Awake runs right after the Constructor for the MonoBehaviour (i.e. right after instantiation).
    OnEnable runs right after the MonoBehaviour is enabled

    When in doubt, have a look at the ExecutionOrder: https://docs.unity3d.com/Manual/ExecutionOrder.html

    • Awake: This function is always called before any Start functions and also just after a prefab
      is instantiated. (If a GameObject is inactive during start up Awake is not called until it is made active.)
    • OnEnable: (only called if the Object is active): This function is called just after the object is enabled. This happens when a MonoBehaviour instance is created, such as when a level is loaded or a GameObject
      with the script component is instantiated.
    • Start: Start is called before the first frame update only if the script instance is enabled. For objects that are part of a scene asset, the Start function is called on all scripts before Update, etc is called for any of them. Naturally, this cannot be enforced when you instantiate an object during gameplay.
    Of course you can also always add your own Init()-method which you call after instantiation.
     
    Daviiid likes this.