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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Initialization inside Start() or Awake()?

Discussion in 'Scripting' started by BadSeedProductions, Mar 19, 2015.

  1. BadSeedProductions

    BadSeedProductions

    Joined:
    Dec 26, 2014
    Posts:
    144
    I've found that sometimes when declaring my variables in C# I get errors. Sometimes moving the lines inside "Start()" fixes the error. How do you determine what needs to be initialized within Start or Awake?
    Thanks,
    -C not so sharp
     
    roshanjafri31_unity likes this.
  2. proandrius

    proandrius

    Unity Technologies

    Joined:
    Dec 4, 2012
    Posts:
    544
    Well Awake just called before Start and while loading unity player where Start is called when game is loaded.
     
  3. BadSeedProductions

    BadSeedProductions

    Joined:
    Dec 26, 2014
    Posts:
    144
    I should have asked that question differently. Not quite sure how to construct it though. Let me show in code:

    This code works. Figure A.
    Code (CSharp):
    1.  
    2. Vector3 myVariable = new Vector3(0,0,0);
    3.  
    4. void Start(){
    5.  
    6. }
    7.  
    This will throw an error. Figure B.
    Code (CSharp):
    1. public GameObject myCamera;
    2.  
    3. Vector3 myVariable = myCamera.transform.position;
    4.  
    5. void Start(){
    6.  
    7. }
    This is correct code. Figure C.
    Code (CSharp):
    1. public GameObject myCamera;
    2.  
    3. void Start(){
    4. Vector3 myVariable = myCamera.transform.position;
    5. }
    error Figure D.
    Code (CSharp):
    1.  
    2. var myVariable = 10;
    3. void Start(){
    4.  
    5. }
    no error Figure E.
    Code (CSharp):
    1.  
    2. void Start(){
    3. var myVariable = 10;
    4. }
    Is this because in Figure A. the stack declares myCamera at the same time and not before myVariable? If that were true how come figure D. throws errors and not E.? And why does Figure A. work while D throws an error?

    Thanks
     
  4. Roderyk

    Roderyk

    Joined:
    Mar 5, 2015
    Posts:
    75
    Because the last one you are using primitives types.
    In the first ones, the gameObject won't let you assing those things outside of Awake or Start.
     
  5. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Do internal initialization in Awake and initialization that relies on other GameObjects in the scene in Start. Awake is called after the object is fully initialized and Start is called after *every* object is.
     
    sean244 and MercurialKid like this.
  6. Mr-Mud

    Mr-Mud

    Joined:
    Mar 8, 2015
    Posts:
    37
    About example A,B and C: You cannot use the currently created instance for field initialization outside of functions. Since the transform property is a (disguised) instance method, you cannot use it. And even if you could, reference values might not even be initialized yet; which would result in null reference exceptions. Here is some documentation from Microsoft.

    About samples D and E: In C#, you can only use the var keyword in local scope; basically methods only. So that should explain it. See the link for a more detailed description about it.
     
  7. BadSeedProductions

    BadSeedProductions

    Joined:
    Dec 26, 2014
    Posts:
    144
    So primitive data types must me initialized within a function? Is this C# specific? (or javascript as well?)

    Mr. Mud: So primitive data types must be initialized within a method? Thanks, very helpful!
     
  8. Mr-Mud

    Mr-Mud

    Joined:
    Mar 8, 2015
    Posts:
    37
    Not quite. You can access static fields/methods (this includes fields marked as const(ant)); even outside of methods.

    Values assigned to other instance fields, or that you retrieve from methods/properties cannot be assigned outside of functions.
     
  9. Roderyk

    Roderyk

    Joined:
    Mar 5, 2015
    Posts:
    75
    No.
    What I meant to say is that it did work because you use primitives.
    Your real problem in D is that you said your myVariable is of type VAR. If you want to create the variable outside of the Start or Awake method, you need to specify the type (int, float, etc).

    If I'm not mistaken.
     
  10. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    No you don't. This works fine.
    Code (csharp):
    1.  
    2. public class SomeClass : MonoBehaviour
    3. {
    4.     var someList = new List<GameObject>();
    5. }
    6.  
    This is bad
    Code (csharp):
    1.  
    2. public class SomeClass : MonoBehaviour
    3. {
    4.     var someList;
    5.  
    6.     void Awake()
    7.     {
    8.         someList = new List<GameObject>();
    9.     }
    10. }
    11.  
     
  11. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Usually I initialize variables in Awake and do things with them in Start. This way, I never see any null reference exceptions even when communicating with other scripts.
     
  12. BadSeedProductions

    BadSeedProductions

    Joined:
    Dec 26, 2014
    Posts:
    144
    Thanks, I'll have to try that
     
  13. Mad-Strategist

    Mad-Strategist

    Joined:
    May 2, 2015
    Posts:
    4
    I have found this was confusing for me:
    In a new created script there is a comment for Start - "use this for initialization". And there's no Awake.
    But in the documentation for Start() and Awake() stays that sometimes initialization should be done in Awake and sometimes in Start.
     
  14. Duugu

    Duugu

    Joined:
    May 23, 2015
    Posts:
    241
    As previously mentioned it depends on what you would like to initialize.
    Local script stuff that could be accessed by other scripts = awake
    Anything else plus stuff that uses external (to the script) references = start