I’ve tried a bunch of different implementations, and trawled everything online I could get my hands on. Everything has downsides, nothing plays nicely with how Unity wants you to work.
Let’s keep it simple. You want to track in-game time. You want this to be available as a ScriptableObject. You need a MonoBehaviour to keep the time updated. You want to ensure there’s just one such GameState ScriptableObject and one such GameStateManager MonoBehaviour. You don’t want to manually add the manager to all scenes.
Is there a standard and sane way to achieve this without resorting to black magic?
To keep this grounded, here’s the boilerplate ScriptableObject:
[CreateAssetMenu(fileName = "GameState", menuName = "ScriptableObjects/GameState")]
public class GameState : ScriptableObject {
///
/// The time passed in game, in game time, in seconds.
///
public float TimePassed { get; private set; } = 0.0f;
///
/// Moves the in-game time and date forward.
///
/// Time to add, in in-game seconds.
public void MoveTimeForward(float addedGameTime) {
// Move the time passed forward
TimePassed += addedGameTime;
}
}
And MonoBehaviour:
public class GameStateManager : MonoBehaviour {
///
/// The state of the game.
///
public GameState gameState;
// Start is called before the first frame update
void Start() {
// If we use a Singleton, and not drag a reference using the editor:
gameState = GameState.Instace;
// Mark that this should not to be destroyed when loading new scenes
DontDestroyOnLoad(gameObject);
}
// Update is called once per frame
void Update() {
// Update the in-game time
gameState.MoveTimeForward(Time.deltaTime);
}
}
No comments:
Post a Comment