Skip to content

Instantly share code, notes, and snippets.

@daltonbr
Created October 14, 2018 02:57
Show Gist options
  • Save daltonbr/0236ef8fe592d8beb006609a53c84911 to your computer and use it in GitHub Desktop.
Save daltonbr/0236ef8fe592d8beb006609a53c84911 to your computer and use it in GitHub Desktop.
SOLID Principles - Dependency Injection (not dependency inversion)
using UnityEngine;
public class AiInput : IShipInput
{
public float Rotation { get; private set;}
public float Thrust { get; private set;}
public void ReadInput()
{
Rotation = Random.Range(-1f, 1f);
Thrust = Random.Range(-1f, 1f);
}
}
using UnityEngine;
public class ControllerInput : IShipInput
{
public float Rotation { get; private set;}
public float Thrust { get; private set;}
public void ReadInput()
{
Rotation = Input.GetAxis("Horizontal");
Thrust = Input.GetAxis("Vertical");
}
}
public interface IShipInput
{
void ReadInput();
float Rotation { get; }
float Thrust { get; }
}
using UnityEngine;
// From here to above codes, we are using a better approach, using Dependency Injection
public class Ship : MonoBehaviour
{
[SerializeField] private ShipSettings shipSettings;
private IShipInput shipInput;
private ShipMotor shipMotor;
private void Awake()
{
shipInput = shipSettings.UseAi ? new AiInput() as IShipInput : new ControllerInput();
// ShipMotor isn't a MonoBehaviour, it doesn't need to be
shipMotor = new ShipMotor(shipInput, transform, shipSettings);
}
private void Update()
{
shipInput.ReadInput();
shipMotor.Tick();
}
}
using UnityEngine;
public class ShipMotor
{
private readonly IShipInput shipInput;
private readonly Transform transformToMove;
private readonly ShipSettings shipSettings;
public ShipMotor(IShipInput shipInput, Transform transformToMove, ShipSettings shipSettings)
{
this.shipInput = shipInput;
this.transformToMove = transformToMove;
this.shipSettings = shipSettings;
}
public void Tick()
{
transformToMove.Rotate(Vector3.up * shipInput.Rotation * Time.deltaTime * shipSettings.TurnSpeed);
tranformToMove.position += transformToMove.forward * shipInput.Thrust * Time.deltaTime * shipSettings.MoveSpeed;
}
}
using UnityEngine;
public class ShipMotorOriginal : MonoBehaviour
{
[SerializeField] private float turnSpeed = 15f;
[SerializeField] private float moveSpeed = 10f;
private void Update()
{
// We are handling input, so it breaks the single responsibility principle
float rotation = Input.GetAxis("Horizontal");
float thrust = Input.GetAxis("Vertical");
transform.Rotate(Vector3.up * rotation * Time.deltaTime * turnSpeed);
transform.position += transform.forward * thrust * Time.deltaTime * moveSpeed;
}
}
using UnityEngine;
public class ShipMotorSplit : MonoBehaviour
{
[SerializeField] private float turnSpeed = 15f;
[SerializeField] private float moveSpeed = 10f;
private ShipInputSplit shipInput;
private void Awake()
{
// we can have a SetInput() method, so swap the input to use with AI or Network
shipInput = GetComponent<ShipInputSplit>();
}
private void Update()
{
float rotation = shipInput.Rotation;
float thrust = shipInput.Thrust;
transform.Rotate(Vector3.up * rotation * Time.deltaTime * turnSpeed);
transform.position += transform.forward * thrust * Time.deltaTime * moveSpeed;
}
}
using UnityEngine;
[CreateAssetMenu(menuName = "Ship/Settings", fileName = "ShipData")]
public class ShipSettings : ScriptableObject
{
[SerializeField] private float turnSpeed = 25f;
[SerializeField] private float moveSpeed = 10f;
[SerializeField] private bool useAi = false;
public float TurnSpeed { get { return turnSpeed; } }
public float MoveSpeed { get { return moveSpeed; } }
public bool UseAi { get { return useAi; } }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment