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?
Have you seen this? Github link at the end of the blog post:
If I’ve understood it right, your “energy” is only a variable to control if u can or not fire some weapons right?
Yes, check if you can do something, and if you can, consume some energy
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
[CreateAssetMenu]
public class IntVariable
{
[SerializeField]
[Multiline] private string DeveloperDescription = "";
[Header("Will have an default value?")]
public bool haveDefaultValue = false;
[Header("Default/Current value")]
[SerializeField] private int value;
[Header("Debug")]
[SerializeField] private int runTimeValue;
public int Value
{
get => haveDefaultValue ? runTimeValue : value;
set
{
if (haveDefaultValue)
runTimeValue = value;
else
this.value = value;
}
}
private void OnEnable()
{
if (haveDefaultValue)
runTimeValue = value;
}
private void OnDisable()
{
if (haveDefaultValue)
runTimeValue = value;
}
}
- 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