using System; using Grid; using UnityEngine; namespace Actions { public class UnitActionSystem : MonoBehaviour { [SerializeField] private LayerMask UnitsLayerMask; [SerializeField] private Unit selectedUnit; public static UnitActionSystem Instance { get; private set; } private bool IsBusy { get; set; } public BaseAction SelectedAction { get; set; } public Unit SelectedUnit { get => selectedUnit; private set => selectedUnit = value; } private void Awake() { if (Instance is not null) { Debug.LogError($"There is more than one UnitActionSystem! {transform} - {Instance}"); Destroy(gameObject); return; } Instance = this; } private void Start() => SetSelectedUnit(SelectedUnit); private void Update() { if (IsBusy) return; if (TryHandleUnitSelection()) return; if (SelectedUnit is not null) HandleSelectedAction(); } private void HandleSelectedAction() { if (!Input.GetMouseButtonDown(0)) return; GridPosition mouseGridPosition = LevelGrid.Instance.GetGridPosition(MouseWorld.GetPosition()); switch (SelectedAction) { case MoveAction moveAction: if (moveAction.IsValidActionGridPosition(mouseGridPosition)) { moveAction.Move(mouseGridPosition, ClearBusy); IsBusy = true; } break; case SpinAction spinAction: spinAction.Spin(ClearBusy); IsBusy = true; break; } } private void ClearBusy() => IsBusy = false; public event EventHandler OnSelectedUnitChanged; private bool TryHandleUnitSelection() { if (!Input.GetMouseButtonDown(0)) return false; if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit raycastHit, float.MaxValue, UnitsLayerMask)) return false; if (!raycastHit.transform.TryGetComponent(out Unit unit) || unit is null) return false; SetSelectedUnit(unit); return true; } private void SetSelectedUnit(Unit unit) { SelectedUnit = unit; SelectedAction = unit.MoveAction; OnSelectedUnitChanged?.Invoke(this, EventArgs.Empty); } } }