using System; using Grid; using UnityEngine; using UnityEngine.EventSystems; 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; private 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 (EventSystem.current.IsPointerOverGameObject()) 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()); if (!SelectedAction.IsValidActionGridPosition(mouseGridPosition)) return; IsBusy = true; SelectedAction.TakeAction(mouseGridPosition, ClearBusy); } private void ClearBusy() => IsBusy = false; public event EventHandler OnSelectedUnitChanged; public event EventHandler OnSelectedActionChanged; 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; if (unit == selectedUnit) return false; SetSelectedUnit(unit); return true; } private void SetSelectedUnit(Unit unit) { SelectedUnit = unit; SelectedAction = unit.MoveAction; OnSelectedUnitChanged?.Invoke(this, EventArgs.Empty); } public void SetSelectedAction(BaseAction baseAction) { SelectedAction = baseAction; OnSelectedActionChanged?.Invoke(this, EventArgs.Empty); } } }