In this lesson, you will learn how to encapsulate reusable game logic into ScriptableObject assets so you can trigger complex actions from anywhere in your project without hard-coding dependencies.
The Concept of a Game Action
Normally, if you want a button to play a sound and spawn a particle effect, you might write a script that explicitly references those specific components. This creates tight coupling, making your code hard to maintain. Instead, we can create a GameAction—a ScriptableObject that acts as a standardized "command" object. By defining an abstract Execute() method, we can create various actions (like SpawnAction or PlaySoundAction) that all share the same interface.
Implementing the Base Action
First, we create a base class to define what every action looks like:
public abstract class GameAction : ScriptableObject
{
public abstract void Execute();
}
Now, we can create a specific action, such as a SpawnAction, which holds a reference to a Prefab:
[CreateAssetMenu(menuName = "Actions/Spawn Action")]
public class SpawnAction : GameAction
{
public GameObject prefabToSpawn;
public override void Execute()
{
Instantiate(prefabToSpawn);
}
}
Triggering the Action
The power here lies in the fact that your UI button or collision trigger doesn't need to know what the action does; it only needs to know that it has a GameAction to execute. You can create an instance of your SpawnAction as an asset in your Project window, assign the desired Prefab in the Inspector, and drag that asset into any script that needs to fire it.
When you call myAction.Execute(), the system performs its logic regardless of whether it’s spawning an object, playing a sound, or changing a game state. This decouples your systems entirely, allowing you to swap out behaviors simply by changing the ScriptableObject asset assigned to a field, rather than modifying your core gameplay scripts.
Key Takeaway: By moving logic into ScriptableObject-based actions, you turn specific code tasks into modular, swappable assets that can be triggered by any system without creating direct dependencies.