Search Unity

float? (with question mark), what it is?

Discussion in 'Scripting' started by Karwoch, Sep 22, 2016.

  1. Karwoch

    Karwoch

    Joined:
    Sep 16, 2014
    Posts:
    111
    I`m trying to do trajectory path for my game, and I found useful script to do that, but for first time I see use of float? in the code. I thought it is some code mistake on website, but apparently VS reconize this, but I can`t find any documentation about that. What does it do? Here is code sample:


    Code (CSharp):
    1.     void RotateGun()
    2.     {
    3.         //Get the 2 angles
    4.         float? highAngle = 0f;
    5.         float? lowAngle = 0f;
    6.  
    7.         CalculateAngleToHitTarget(out highAngle, out lowAngle);
    8.  
    9.         //Artillery
    10.         float angle = (float)highAngle;
    11.         //Regular gun
    12.         //float angle = (float)lowAngle;
    13.  
    14.         //If we are within range
    15.         if (angle != null)
    16.         {
    17.             //Rotate the gun
    18.             //The equation we use assumes that if we are rotating the gun up from the
    19.             //pointing "forward" position, the angle increase from 0, but our gun's angles
    20.             //decreases from 360 degress when we are rotating up
    21.             gunObj.localEulerAngles = new Vector3(360f - angle, 0f, 0f);
    22.  
    23.             //Rotate the turret towards the target
    24.             transform.LookAt(targetObj);
    25.             transform.eulerAngles = new Vector3(0f, transform.rotation.eulerAngles.y, 0f);
    26.         }
    27.     }
    28.  
    29.     //Which angle do we need to hit the target?
    30.     //Returns 0, 1, or 2 angles depending on if we are within range
    31.     void CalculateAngleToHitTarget(out float? theta1, out float? theta2)
    32.     {
    33.         //Initial speed
    34.         float v = bulletSpeed;
    35.  
    36.         Vector3 targetVec = targetObj.position - gunObj.position;
    37.  
    38.         //Vertical distance
    39.         float y = targetVec.y;
    40.  
    41.         //Reset y so we can get the horizontal distance x
    42.         targetVec.y = 0f;
    43.  
    44.         //Horizontal distance
    45.         float x = targetVec.magnitude;
    46.  
    47.         //Gravity
    48.         float g = 9.81f;
    49.  
    50.  
    51.         //Calculate the angles
    52.  
    53.         float vSqr = v * v;
    54.  
    55.         float underTheRoot = (vSqr * vSqr) - g * (g * x * x + 2 * y * vSqr);
    56.  
    57.         //Check if we are within range
    58.         if (underTheRoot >= 0f)
    59.         {
    60.             float rightSide = Mathf.Sqrt(underTheRoot);
    61.  
    62.             float top1 = vSqr + rightSide;
    63.             float top2 = vSqr - rightSide;
    64.  
    65.             float bottom = g * x;
    66.  
    67.             theta1 = Mathf.Atan2(top1, bottom) * Mathf.Rad2Deg;
    68.             theta2 = Mathf.Atan2(top2, bottom) * Mathf.Rad2Deg;
    69.         }
    70.         else
    71.         {
    72.             theta1 = null;
    73.             theta2 = null;
    74.         }
    75.     }
     
  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,406
    BitGamey and Karwoch like this.
  3. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    If you want even more information C# has a System defined Struct called Nullable<T>
    https://msdn.microsoft.com/en-us/library/b3h38hb0.aspx

    Code (CSharp):
    1. float? highAngle;
    is just shorthand for
    Code (CSharp):
    1. Nullable<float> highAngle = new Nullable<float>();
    In general in C# anything that is a reference type variable (like classes) are nullable inherently and can't use the ? syntax

    Value type variables (floats, int, structs) can't be null so you need to use ? to make them able to equal a null. (this is different than equaling 0).
     
    ArturMGS and Karwoch like this.
  4. Karwoch

    Karwoch

    Joined:
    Sep 16, 2014
    Posts:
    111
    Ah, and I was searching for this! I mean nullable float, and I didn`t knew it was so simple! So it means that this code has flaw - angle isn`t declared as nullable - so angle != null won`t work.

    Thank You!!!
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,332
    If you rewrite CalculateAngleToHitTarget to return true/false to indicate if it could find an angle instead of putting null in the out parameters, you can drop the whole nullable thing.
     
    Kiwasi likes this.
  6. Karwoch

    Karwoch

    Joined:
    Sep 16, 2014
    Posts:
    111
    You are right, I also never worked with custom "out" parameters, didn`t thought about using function return with out parameter, thanks! :)
     
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    You probably haven't seen it much because making a struct nullable isn't very popular in C#. There is seldom a need for it, and in many cases it makes program logic harder to follow.
     
    LiterallyJeff likes this.
  8. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Its rarely useful for returning things. Like @Baste said just using bool to return true/false works just as well as setting the parameter to null. However, I have found it handy when you taking a struct as an input parameter. You might have a struct with say 6 variables in it that the you fill in and pass to the function, but sometimes you just want to use the default ones so you can just pass in a null. Then the function checks for null and uses all the default values.
     
    Kiwasi likes this.