Search Unity

C# Variable Types

Discussion in 'Scripting' started by rmele09, May 29, 2015.

  1. rmele09

    rmele09

    Joined:
    Nov 8, 2010
    Posts:
    716
    I am switching over from javascript and I am confused about some of the variable types. What types of variables are these below (written in javascript) and how do you set them:

    var myController = freyaPlayer.GetComponent.<CharacterController>();

    anim = GetComponent.<Animation>();


    Thanks!
     
  2. Bradamante

    Bradamante

    Joined:
    Sep 27, 2012
    Posts:
    300
    Should be:

    Code (csharp):
    1. CharacterController myController = freyaPlayer.GetComponent<CharacterController>();
    2.  
    3. Animation anim = GetComponent<Animation>();
    4. // could also be: this.GetComponent<Animation>();
    5.  
    You can use var in C# too, but it's less explicit, which is why I would advise against it.
     
    Last edited: May 30, 2015
  3. rmele09

    rmele09

    Joined:
    Nov 8, 2010
    Posts:
    716
    I tried the variable like this and get an error:

    CharacterController myController = freyaPlayer.GetComponent.<CharacterController>();

    error:

    Unexpected symbol `<', expecting `identifier'
     
  4. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    It's GetComponent<CharacterController>();

    No period after GetComponent.
     
  5. rmele09

    rmele09

    Joined:
    Nov 8, 2010
    Posts:
    716
    ok, now I try this and get another error:

    Animation anim = GetComponent<Animation>();

    A field initializer cannot reference the nonstatic field, method, or property `UnityEngine.Component.GetComponent(System.Type)'
     
  6. willemsenzo

    willemsenzo

    Joined:
    Nov 15, 2012
    Posts:
    585
    You can't make a GetComponent call outside of any function. So if you have ANY variable in your class that uses GetComponent to initialize you have to call GetComponent from within some function.

    So this would work:

    Animation anim;

    void Start()
    {
    anim = GetComponent<Animation>();
    }

    And this should not work (unless you put the entire line in a function):

    Animation anim = GetComponent<Animation>();
     
  7. rmele09

    rmele09

    Joined:
    Nov 8, 2010
    Posts:
    716
    Thank you very good explanation.

    One last quick example of a variable. Let's say I set something up like this, I am using this new variable incorrectly and getting an error, what needs to change?

    Transform playDeath = GameObject.FindWithTag("FreyaArms").transform;
    playDeath.GetComponent<FreyaArms>().playDeath = true;

    error:

    Assets/Scripts/Freya.cs(240,25): error CS0246: The type or namespace name `FreyaArms' could not be found. Are you missing a using directive or an assembly reference?
     
  8. willemsenzo

    willemsenzo

    Joined:
    Nov 15, 2012
    Posts:
    585
    That error usually means you either spelled something wrong or the script you're refering to doesn't exist/can't be found.

    By the way you can't do a GetComponent call on a transform. Look again, you declared the playDeath variable as a Transform type, yet on the next line you try to call GetComponent on it, which you can only do on GameObject types.
     
  9. rmele09

    rmele09

    Joined:
    Nov 8, 2010
    Posts:
    716
    So is the type wrong? I tried GameObject before and I think I got an error. I must be declaring the variable wrong because it works in javascript.
     
  10. willemsenzo

    willemsenzo

    Joined:
    Nov 15, 2012
    Posts:
    585
    I forgot to mention that what I explained about GetComponent calls also counts for GameObject.Find and/or any other function. You can't call functions (because that's what they are) outside of a function.
     
  11. Bradamante

    Bradamante

    Joined:
    Sep 27, 2012
    Posts:
    300
    Well, that should work. I find it a bit unusual that both the component and the tag have the same name ... but maybe that's correct.

    Quick note: That doesn't look like good coding style. Look at something like:

    Code (csharp):
    1. GameObject.FindWithTag("FreyaArms").SendMessage ( "OnSetPlayDeath" );
    where the OnSetPlayDeath function would then set the variable. SendMessage is not that great either, though. Look at the techniques described here.

    Actually you can, I assume they added that for conveniance. I guess

    Code (csharp):
    1. transform.GetComponent<Component>();
    internally gets converted to

    Code (csharp):
    1. transform.gameObject.GetComponent<Component>();
    You can also do

    Code (csharp):
    1. transform.SendMessage ( "OnEvent" );
     
    Last edited: May 30, 2015
  12. rmele09

    rmele09

    Joined:
    Nov 8, 2010
    Posts:
    716
    Thanks for the answer you are being very helpful. I hate c# haha. If you have time, I am also getting an error on this IEnumerator.

    // Left Cast Out
    public bool playLeftCastOut = true;

    IEnumerator LeftCastOut()
    {
    playLeftCastOut = false;
    GetComponent<Animation>().CrossFade("FA_Idle");
    playLeftCastOut = true;
    }

    error:
    : not all code paths return a value
     
  13. JasonBricco

    JasonBricco

    Joined:
    Jul 15, 2013
    Posts:
    956
    You must use a yield statement in a coroutine.

    You're treating that like any typical function. If you want it to be, you would put 'void' instead of IEnumerator.

    You would use a coroutine if you want to delay execution of the function or wait for another function to finish running. In this case, if you want to wait until the CrossFade call is finished before setting 'playLeftCastOut' to true, you can yield for the duration of the fade by saying:

    yield return new WaitForSeconds(0.3f);

    (It seems CrossFade's default duration is 0.3, but you would put whatever length you set).
     
  14. rmele09

    rmele09

    Joined:
    Nov 8, 2010
    Posts:
    716
    Thanks man that fixed the errors I was getting, I had like 6 of those. Very helpful knowledge I appreciate the help