Files
2026-05-21 16:04:49 +02:00

96 lines
2.7 KiB
C#

using Cysharp.Threading.Tasks;
using Unity.Mathematics;
using UnityEngine.InputSystem;
namespace DanieleMarotta.RiversongCodeShowcase
{
public abstract class DragTool : EditTool
{
private IPointerService _pointerService;
private ITileSpace _tileSpace;
private bool _isDragging;
private int2 _startTile;
private int2 _endTile;
private bool _isValid;
protected DragTool(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
protected virtual DeletedGameObjectsFilter DeletedGameObjectsFilter => DeletedGameObjectsFilter.None;
public override async UniTask InitializeAsync()
{
await base.InitializeAsync();
_pointerService = ServiceLocator.GetService<IPointerService>();
_tileSpace = ServiceLocator.GetService<ITileSpace>();
}
public override void OnDisabled()
{
base.OnDisabled();
_isDragging = false;
}
public override void Update()
{
base.Update();
AffectedTiles.Clear();
var lmb = Mouse.current.leftButton;
var isPointerOnTerrain = _pointerService.TryGetPositionOnTerrain(out var position);
if (!isPointerOnTerrain)
{
_isDragging &= lmb.isPressed;
_isValid = false;
return;
}
if (!_isDragging)
{
_startTile = _tileSpace.WorldToTile(position);
_endTile = _startTile;
}
_isDragging |= _pointerService.TryConsumeLeftClick();
if (_isDragging && !_pointerService.IsPointerOverUI) _endTile = _tileSpace.WorldToTile(position);
_isValid = Validate(ref _startTile, ref _endTile);
UpdateAffectedTiles(_isValid, _startTile, _endTile);
if (lmb.wasReleasedThisFrame)
{
if (_isValid && !_pointerService.IsPointerOverUI) DoTool(_startTile, _endTile);
_isDragging = false;
}
}
protected abstract bool Validate(ref int2 startTile, ref int2 endTile);
protected abstract void UpdateAffectedTiles(bool isValid, int2 startTile, int2 endTile);
protected abstract void DoTool(int2 startTile, int2 endTile);
public override void GetDeleteGameObjectsPreviewInfo(out DeletedGameObjectsFilter filter, out TileRect rect)
{
if (!_isValid)
{
filter = DeletedGameObjectsFilter.None;
rect = TileRect.Empty;
return;
}
filter = DeletedGameObjectsFilter;
rect = new TileRect(_startTile, _endTile);
}
}
}