I am aiming to create a Unity project with a code structure similar to ECS. I want the code to be consistent, easy to integrate extend and expand if multiple developers will work with it.
By that I mean I want to centralize as much as I can the source of bugs and errors.
For example, if there is a problem with the mouse dragging one object, the source of the bug should be the dragging system class and not a class attached to that object.
So, basically, I want to write common logic once, and centralize as much as possible the source of error.
Before showing a sample of the code, I want to say I come from a professional software development background, so I think there is importance in following guidelines and design patterns to avoid troubles that come with developing large systems instead of dealing with them.
For now a simple drag "system" is implemented. There are 3 classes:
InputManager.csDragManager.csProperties.cs
InputManager.cs detect a drag on an object and raises a Drag event public static event Action<Transform, Vector3> MouseDragEvent, that event is consumed by the DragManager.cs class which takes some properties (isDraggable, dragSpeed) from the Properties.cs class and moves the Transform given as parameter by dragSpeed.
Question: Is this design bad or good? It may be overkill but that seems to satisfy the first paragraph.
Code:
InputsManager.cs
public class InputsManager : MonoBehaviour {
public static event Action<Transform, Vector3> MouseDragEvent;
public static event Action<Transform, Vector3> ObjectClickedEvent;
Ray ray;
RaycastHit rayHit;
DragManager _dragManager;
Transform draggedObject = null;
ClickManager _clickManager;
Transform clickedObject;
// Mouse Buttons States
bool lastMouseButtonDownState = false;
// Use this for initialization
void Start () {
_dragManager = GetComponent<DragManager>();
}
// Update is called once per frame
void Update () {
if (!lastMouseButtonDownState)
{
draggedObject = null;
}
if(draggedObject == null)
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out rayHit))
{
GameObject hitObject = rayHit.collider.gameObject;
if (hitObject != null)
{
Properties hitObjectProperties = hitObject.GetComponent<Properties>();
if (hitObjectProperties != null)
{
if (lastMouseButtonDownState)
{
draggedObject = hitObject.transform;
}
else
{
}
}
}
}
}
if(lastMouseButtonDownState && draggedObject)
{
MouseDragEvent(draggedObject.transform,
Vector3.Scale(Camera.main.ScreenToWorldPoint(Input.mousePosition), new Vector3(1, 1, 0)));
}
lastMouseButtonDownState = Input.GetMouseButton(0);
}
}
DragManager.cs
public class DragManager : MonoBehaviour {
Properties properties;
void Start () {
properties = GetComponent<Properties>();
InputsManager.MouseDragEvent += Drag;
}
public void Drag (Transform target, Vector3 newPosition) {
Debug.Log(target);
target.position = newPosition;
}
}
Properties.cs
public class Properties: MonoBehaviour {
public bool IsDraggable;
public float DragSpeed;
}