Search Unity

Question Creating a method that may not return anything?

Discussion in 'Scripting' started by dannyryba, Aug 23, 2020.

  1. dannyryba

    dannyryba

    Joined:
    Jun 22, 2020
    Posts:
    45
    Hi everyone,

    I am creating a simple item drop system in my game. I have a method that generates a random number, then uses a switch statement to generate an item and pass it along to another script.

    However, I have run into an issue - I don't want all switches to return a value. I basically want there be a chance that an item will not drop, and therefore the method does not return anything.

    How can I do this? Currently this is my code:

    Code (CSharp):
    1. public class ItemDrops
    2. {
    3.     int randomNumber;
    4.     [SerializeField] GameObject weapon1;
    5.     [SerializeField] GameObject weapon2;
    6.     [SerializeField] GameObject weapon3;
    7.  
    8.     public GameObject ItemGenerated()
    9.     {
    10.         randomNumber = Random.Range(0, 12);
    11.         switch(randomNumber)
    12.         {
    13.             case 1:
    14.                 return weapon1;
    15.             case 2:
    16.                 return weapon2;
    17.             case 3:
    18.                 return weapon3;
    19.             default:
    20.                 break;
    21.         }
    22.     }
    23. }
    Obviously, since not all values return something, I have an error.

    Hopefully this is just something simple or there is another way of doing this I am not familiar with :)
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    You could return a null, then have the locations that call this handle it. That's pretty common practice.

    However, if you have lots of call sites that might be painful.

    Therefore you could return something useless, such as a blank prefab that is an empty gameObject. But then it might show up in your inventory.

    Another thing you could do is have the notion of a "weapon_none" and return that. It could be an invisible gameobject or whatever.

    Basically, all data is just 1s and 0s, and with engineering, we are making choices to make data mean something.

    If you craft your data so that it maps to all the things you want to represent, it helps you reason about the issue.
     
    dannyryba likes this.
  3. dannyryba

    dannyryba

    Joined:
    Jun 22, 2020
    Posts:
    45
    Thanks for the reply! Can you elaborate about how I would go about handling this? This method is actually only being called in one place, so this might actually be the best option.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    I guess a start would be,

    Code (csharp):
    1. GameObject item = ItemGenerated();
    2.  
    3. if (item != null)
    4. {
    5.   // do something with the generated GameObject (instantiate it or whatever)
    6.  
    7.   // instantiate and replace the reference for ease
    8.   item = Instantiate<GameObject>( item);
    9.   // etc...
    10.  
    11.   Debug.Log( "You got a " + go.name);
    12. }
    13. else
    14. {
    15.   // otherwise don't!
    16.   Debug.Log( "You got swindled... the crate was empty!");
    17. }
     
    dannyryba likes this.
  5. dannyryba

    dannyryba

    Joined:
    Jun 22, 2020
    Posts:
    45
    Unfortunately the problem I am running into is that without all code paths returning a value, I get a compiler error in Unity. So I can't actually apply this logic unless there is a workaround I am unaware of.

    edit: I'm a dummy, I didn't realize you can simply return null!
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    Yessir, this is the magic... for any nullable type you can return a null.

    If you were returning an integer or a Vector3 or float or other value type, that would not be possible, as those are not nullable types. Hopefully that tidbit will save you head scratching in the future!

    Just remember, if you return a null and other code that got it back tries to use it, it's still just a full-on legitimate null reference error, so you have to be sure to test for it.!
     
    dannyryba likes this.
  7. dannyryba

    dannyryba

    Joined:
    Jun 22, 2020
    Posts:
    45
    Thanks so much! It's working perfectly now!
     
    Kurt-Dekker likes this.