Skip to content

Instantly share code, notes, and snippets.

@aprius
Last active November 9, 2022 19:48
Show Gist options
  • Select an option

  • Save aprius/7adee69b4ea1984cb73613e6176bcd86 to your computer and use it in GitHub Desktop.

Select an option

Save aprius/7adee69b4ea1984cb73613e6176bcd86 to your computer and use it in GitHub Desktop.
public class AudioManager: Singleton<AudioManager>
{
// ...
}
public class CommandInvoker
{
private static Stack<ICommand> undoStack = new Stack<ICommand>();
public static void ExecuteCommand(ICommand command)
{
command.Execute();
undoStack.Push(command);
}
public static void UndoCommand()
{
if (undoStack.Count > 0)
{
ICommand activeCommand = undoStack.Pop();
activeCommand.Undo();
}
}
}
public interface IProduct
{
public string ProductName { get; set; }
public void Initialize();
}
public abstract class Factory : MonoBehaviour
{
public abstract IProduct GetProduct(Vector3 position);
// other method
}
public class Gamemanager: Singleton<Gamemanager>
{
// ...
}
public interface ICommand
{
void Execute();
void Undo();
}
public class IdleState : IState
{
private PlayerController player;
public IdleState(PlayerController player)
{
this.player = player;
}
public void Enter()
{
// code that runs when we first enter the state
}
public void Update()
{
// Here we add logic to detect if the conditions exist to
// transition to another state
}
public void Exit()
{
// code that runs when we exit the state
}
}
public interface IState
{
public void Enter()
{
// code that runs when we first enter the state
}
public void Update()
{
// per-frame logic, include condition to transition to a new
state
}
public void Exit()
{
// code that runs when we exit the state
}
}
public class MoveCommand : ICommand
{
PlayerMovement playerMovement;
Vector3 movement;
public MoveCommand(playerMovement player, Vector3 moveVector)
{
this.playerMovement = player;
this.movement = moveVector;
}
public void Execute()
{
playerMovement.Move(movement);
}
public void Undo()
{
playerMovement.Move(-movement);
}
}
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private LayerMask obstacleLayer;
private const float boardSpacing = 1f;
public void Move(Vector3 movement)
{
transform.position = transform.position + movement;
}
public bool IsValidMove(Vector3 movement)
{
return !Physics.Raycast(transform.position, movement, boardSpacing, obstacleLayer);
}
}
public class NewBehaviourScript : MonoBehaviour
{
public GameObject prefab;
public GameObject go;
private void Start()
{
Profiler.BeginSample("Instantiate");
Instantiate(prefab);
Profiler.EndSample();
Profiler.BeginSample("Enable");
go.SetActive(true);
Profiler.EndSample();
}
}
public class ObjectPool : MonoBehaviour
{
[SerializeField] private uint initPoolSize;
[SerializeField] private PooledObject objectToPool;
// store the pooled objects in a collection
private Stack<PooledObject> stack;
private void Start()
{
SetupPool();
}
// creates the pool (invoke when the lag is not noticeable)
private void SetupPool()
{
stack = new Stack<PooledObject>();
PooledObject instance = null;
for (int i = 0; i < initPoolSize; i++)
{
instance = Instantiate(objectToPool);
instance.Pool = this;
instance.gameObject.SetActive(false);
stack.Push(instance);
}
}
// returns the first active GameObject from the pool
public PooledObject GetPooledObject()
{
// if the pool is not large enough, instantiate a new PooledObjects
if (stack.Count == 0)
{
PooledObject newInstance = Instantiate(objectToPool);
newInstance.Pool = this;
return newInstance;
}
// otherwise, just grab the next one from the list
PooledObject nextInstance = stack.Pop();
nextInstance.gameObject.SetActive(true);
return nextInstance;
}
public void ReturnToPool(PooledObject pooledObject)
{
stack.Push(pooledObject);
pooledObject.gameObject.SetActive(false);
}
public class PooledObject : MonoBehaviour
{
private ObjectPool pool;
public ObjectPool Pool { get => pool; set => pool = value; }
public void Release()
{
pool.ReturnToPool(this);
}
}
public class ProductA : MonoBehaviour, IProduct
{
[SerializeField] private string productName = "ProductA";
public string ProductName { get => productName; set => productName = value ; }
private ParticleSystem particleSystem;
public void Initialize()
{
// any unique logic to this product
gameObject.name = productName;
particleSystem = GetComponentInChildren<ParticleSystem>();
particleSystem?.Stop();
particleSystem?.Play();
}
}
public class ConcreteFactoryA : Factory
{
// used to create a Prefab
[SerializeField] private ProductA productPrefab;
public override IProduct GetProduct(Vector3 position)
{
// create a Prefab instance and get the product component
GameObject instance = Instantiate(productPrefab.gameObject, position, Quaternion.identity);
ProductA newProduct = instance.GetComponent<ProductA>();
// each product contains its own logic
newProduct.Initialize();
return newProduct;
}
}
using UnityEngine.Pool;
public class RevisedGun : MonoBehaviour
{
// stack-based ObjectPool available with Unity 2021 and above
private IObjectPool<RevisedProjectile> objectPool;
// throw an exception if we try to return an existing item, alread in the pool
[SerializeField] private bool collectionCheck = true;
// extra options to control the pool capacity and maximum size
[SerializeField] private int defaultCapacity = 20;
[SerializeField] private int maxSize = 100;
private void Awake()
{
objectPool = new ObjectPool<RevisedProjectile>(CreateProjec - tile,
OnGetFromPool,
OnReleaseToPool,
OnDestroyPooledObject,
collectionCheck,
defaultCapacity,
maxSize);
}
// invoked when creating an item to populate the object pool
private RevisedProjectile CreateProjectile()
{
RevisedProjectile projectileInstance = Instantiate(projec - tilePrefab);
projectileInstance.ObjectPool = objectPool;
return projectileInstance;
}
// invoked when returning an item to the object pool
private void OnReleaseToPool(RevisedProjectile pooledObject) { pooledObject.gameObject.SetActive(false); }
// invoked when retrieving the next item from the object pool
private void OnGetFromPool(RevisedProjectile pooledObject) { pooledObject.gameObject.SetActive(true); }
// invoked when we exceed the maximum number of pooled items (i.e.destroy the pooled object)
private void OnDestroyPooledObject(RevisedProjectile pooledObject) { Destroy(pooledObject.gameObject); }
private void FixedUpdate() { }
}
public class RevisedProjectile : MonoBehaviour
{
private IObjectPool<RevisedProjectile> objectPool;
// public property to give the projectile a reference to its ObjectPool
public IObjectPool<RevisedProjectile> ObjectPool { set => objectPool = value; }
}
private void RunPlayerCommand(PlayerMovement player, Vector3 movement)
{
if (player == null)
{
return;
}
if (player.IsValidMove(movement))
{
ICommand command = new MoveCommand(player, movement);
CommandInvoker.ExecuteCommand(command);
}
}
using UnityEngine;
public class SimpleSingleton : MonoBehaviour
{
public static SimpleSingleton Instance;
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else
{
Destroy(gameObject);
}
}
}
public class Singleton : MonoBehaviour
{
private static Singleton instance;
public static Singleton Instance
{
get
{
if (instance == null)
{
SetupInstance();
}
return instance;
}
}
private void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(this.gameObject);
}
else
{
Destroy(gameObject);
}
}
private static void SetupInstance()
{
instance = FindObjectOfType<Singleton>();
if (instance == null)
{
GameObject gameObj = new GameObject();
gameObj.name = "Singleton";
instance = gameObj.AddComponent<Singleton>();
DontDestroyOnLoad(gameObj);
}
}
}
public class Singleton<T> : MonoBehaviour where T : Component
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
instance = (T)FindObjectOfType(typeof(T));
if (instance == null)
{
SetupInstance();
}
}
return instance;
}
}
public virtual void Awake()
{
RemoveDuplicates();
}
private static void SetupInstance()
{
instance = (T)FindObjectOfType(typeof(T));
if (instance == null)
{
GameObject gameObj = new GameObject();
gameObj.name = typeof(T).Name;
instance = gameObj.AddComponent<T>();
DontDestroyOnLoad(gameObj);
}
}
private void RemoveDuplicates()
{
if (instance == null)
{
instance = this as T;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
public enum PlayerControllerState
{
Idle,
Walk,
Jump
}
public class UnrefactoredPlayerController : MonoBehaviour
{
private PlayerControllerState state;
private void Update()
{
GetInput();
switch (state)
{
case PlayerControllerState.Idle:
Idle();
break;
case PlayerControllerState.Walk:
Walk();
break;
case PlayerControllerState.Jump:
Jump();
break;
}
}
private void GetInput()
{
// process walk and jump controls
}
private void Walk()
{
// walk logic
}
private void Idle()
{
// idle logic
}
private void Jump()
{
// jump logic
}
}
[Serializable]
public class StateMachine
{
public IState CurrentState { get; private set; }
public WalkState walkState;
public JumpState jumpState;
public IdleState idleState;
public void Initialize(IState startingState)
{
CurrentState = startingState;
startingState.Enter();
}
public void TransitionTo(IState nextState)
{
CurrentState.Exit();
CurrentState = nextState;
nextState.Enter();
}
public void Update()
{
if (CurrentState != null)
{
CurrentState.Update();
}
}
}
public StateMachine(PlayerController player)
{
this.walkState = new WalkState(player);
this.jumpState = new JumpState(player);
this.idleState = new IdleState(player);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment