Skip to content

Instantly share code, notes, and snippets.

@DirtyHarryE
Last active March 6, 2023 17:42
Show Gist options
  • Save DirtyHarryE/915879892759337d30843fccb19b10b2 to your computer and use it in GitHub Desktop.
Save DirtyHarryE/915879892759337d30843fccb19b10b2 to your computer and use it in GitHub Desktop.
Game State
using System;
using UnityEngine;
/*
============================================================================================================================================================
GameState : A static helper class for GameState<T>. Holds the Current State and handles Transitions (calls OnEnter and OnExit where Necessary).
Necessary, since interfaces cannot have static members, and generic classes' static members are not shared across different types.
GameState<T> : The actual State Object. Can be referenced via Singleton Instance.
IGameState : An interface that is implemented by GameState<T>. This allows the static GameState to hold a static reference to a GameState<T> that
is not tied to the generic parameter.
============================================================================================================================================================
*/
public static class GameState
{
internal static IGameState i_Current;
public static GameState<T> GetCurrent<T>() where T : GameState<T>, new()
{
GameState<T> gst = i_Current as GameState<T>;
return gst;
}
public static IGameState Current => i_Current;
private static void Transition(IGameState state)
{
if (i_Current == state)
{
return;
}
if (i_Current != null)
{
i_Current.End();
}
i_Current = state;
i_Current.Start();
}
public static void TransitionTo<T>()
where
T : GameState<T>, IGameState,
new()
{
Transition(GameState<T>.Instance);
}
public static void TransitionTo<T>(GameState<T> state)
where
T : GameState<T>, IGameState,
new()
{
Transition(state);
}
public static void Update()
{
if (i_Current != null)
{
i_Current.Update();
}
}
public static void FixedUpdate()
{
if (i_Current != null)
{
i_Current.FixedUpdate();
}
}
}
public abstract class GameState<T>
: Singleton<T>,
IGameState
where T : GameState<T>, new()
{
protected GameState() : base()
{
if ( GameState.i_Current != null )
{
return;
}
Debug.Log("Setting default " + this);
GameState.TransitionTo(this);
}
void IGameState.Start()
{
OnStart();
}
void IGameState.Update()
{
OnUpdate();
}
void IGameState.FixedUpdate()
{
OnFixedUpdate();
}
void IGameState.End()
{
OnEnd();
}
protected virtual void OnStart() { }
protected virtual void OnUpdate() { }
protected virtual void OnFixedUpdate() { }
protected virtual void OnEnd() { }
}
public interface IGameState
{
void Start();
void Update();
void FixedUpdate();
void End();
}
using System;
public abstract class Singleton<T> where T : Singleton<T>
{
private static T _instance;
public static T Instance
{
get
{
if (_instance == null)
{
// Use Activator.CreateInstance to allow singletons to have private constructors
_instance = Activator.CreateInstance(typeof(T), true) as T;
}
return _instance;
}
}
public static bool Instantiated => _instance != null;
}
using UnityEngine;
using System.Collections;
public class TestState : GameState<TestState> {
Camera mainCamera;
GameObject prefab;
protected override void OnStart()
{
prefab = GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/Po_Character"));
GameObject camGO = GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/MainCamera"));
mainCamera = camGO.GetComponent<Camera>();
}
protected override void OnUpdate()
{
float t = 0.1f;
mainCamera.transform.position = new Vector3(
Mathf.Lerp(mainCamera.transform.position.x, prefab.transform.position.x, t),
Mathf.Lerp(mainCamera.transform.position.y, prefab.transform.position.y, t),
-10
);
}
protected override void OnFixedUpdate()
{
}
protected override void OnEnd()
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment