Search Unity

Question Muti-class alternative to C# events?

Discussion in 'Scripting' started by Inverzus, Jul 30, 2020.

  1. Inverzus

    Inverzus

    Joined:
    Jun 26, 2020
    Posts:
    12
    So I'm working on a 2D spaceship game and I've given the player ship a script handles the "energy" of the ship. This "energy" is drained while boosting or firing certain weapons. I originally implemented this by having my weapon and movement scripts reference the energy script, but I figured that there had to be a better way to this. So I tried using C# events but halfway into refactoring my code I realized that if I wanted to invoke the event whenever every used, then that would mean my energy script would have to subscribe to a multitude of events and would have to subscribe to more whenever I make another script that requires energy. Is there a way to make something like a "Universal Event" that all my scripts can invoke so that my energy script would only need to subscribe to one?

    Maybe something like putting the events into an interface that the energy script and all the scripts that consume energy will inherit.
    Or does referencing the energy script in every script that uses energy perfectly fine?
     
  2. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    401
  3. Nefisto

    Nefisto

    Joined:
    Sep 17, 2014
    Posts:
    335
    If I've understood it right, your "energy" is only a variable to control if u can or not fire some weapons right?
     
  4. Inverzus

    Inverzus

    Joined:
    Jun 26, 2020
    Posts:
    12
    Yes, check if you can do something, and if you can, consume some energy
     
  5. Nefisto

    Nefisto

    Joined:
    Sep 17, 2014
    Posts:
    335
    Ah, I really suggest that u take a look at this presentation

    It's about good practices for creating decouple code if u are in rush watch only about variable architecture because it's exactly what u want.

    In a nutshell what Ryan suggests is that u create a scriptable object variable, in your case your energy, this energy will exist in assets, so anyone can make a ref to it, now all your class that will change or read about values from this variable only need to create in the script and inject in an editor

    In the video example, he doesn't talk about a basic problem when working with a scriptable object, values don't reset between plays.

    EDIT:

    Bellow, we have all code to work with this kind of architecture

    An proper variable of type that u want to work, in our case an int
    Code (CSharp):
    1. [CreateAssetMenu]
    2. public class IntVariable
    3. {
    4.     [SerializeField]
    5.     [Multiline] private string DeveloperDescription = "";
    6.  
    7.     [Header("Will have an default value?")]
    8.     public bool haveDefaultValue = false;
    9.  
    10.     [Header("Default/Current value")]
    11.     [SerializeField] private int value;
    12.  
    13.     [Header("Debug")]
    14.     [SerializeField] private int runTimeValue;
    15.  
    16.     public int Value
    17.     {
    18.         get => haveDefaultValue ? runTimeValue : value;
    19.         set
    20.         {
    21.             if (haveDefaultValue)
    22.                 runTimeValue = value;
    23.             else
    24.                 this.value = value;
    25.         }
    26.     }
    27.  
    28.     private void OnEnable()
    29.     {
    30.         if (haveDefaultValue)
    31.             runTimeValue = value;
    32.     }
    33.  
    34.     private void OnDisable()
    35.     {
    36.         if (haveDefaultValue)
    37.             runTimeValue = value;
    38.     }
    39. }
    * Check hasDefault to make so reset things betwen plays

    Now the workflow will be - more or less - like this:
    1- Create an variable with right click -> create -> intVariable in your assets
    2- ```public IntVariable energy;``` in each script that will use it
    3- Drag'n drop int variable SO in your new variable using the inspector
    4- Use it as you want with energy.Value (or override some operations)

    U can make more code to turn things easier to work as is said in the video with a "Reference variable" as a new layer. If u want to talk about this or want to see how I use this in my workflow only let me know, I like to speak about it ;P
     
    Last edited: Jul 30, 2020