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

82 lines
2.3 KiB
C#

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UIElements;
namespace DanieleMarotta.RiversongCodeShowcase
{
[Service(typeof(IPointerService))]
[GameSystemGroup(typeof(EarlyGameSystemGroup))]
public class PointerSystem : GameSystem, IUpdatable, IPointerService
{
[InjectService]
private IScene _scene;
[InjectService]
private GameConfig _config;
[InjectService]
private ITileSpace _tileSpace;
[InjectService]
private World _world;
[InjectService]
private UIService _uiService;
private int _leftButtonClickCount;
private Vector3? _positionOnTerrain;
public PointerSystem(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
public bool IsPointerOverUI { get; private set; }
public void Update()
{
_leftButtonClickCount = 0;
UpdateIsPointerOverUIFlag();
UpdatePositionOnTerrain();
}
private void UpdateIsPointerOverUIFlag()
{
var panel = _uiService.UIRoot.RootVisualElement.panel;
var position = Mouse.current.position.ReadValue();
position.y = Screen.height - position.y;
position = RuntimePanelUtils.ScreenToPanel(panel, position);
IsPointerOverUI = panel.Pick(position) != null;
}
private void UpdatePositionOnTerrain()
{
_positionOnTerrain = null;
var ray = _scene.MainCamera.ScreenPointToRay(Mouse.current.position.ReadValue());
if (Physics.Raycast(ray, out var hit, float.PositiveInfinity))
{
if (!Mathf.Approximately(Vector3.Dot(hit.normal, Vector3.up), 1)) return;
if (_tileSpace.GetElevation(hit.point.y) != _config.GeneralSettings.BaseElevation) return;
_positionOnTerrain = hit.point;
}
}
public bool TryGetPositionOnTerrain(out Vector3 position)
{
position = _positionOnTerrain ?? Vector3.zero;
return _positionOnTerrain != null;
}
public bool TryConsumeLeftClick(int maxClickCount = 0)
{
return !IsPointerOverUI && Mouse.current.leftButton.wasPressedThisFrame && _leftButtonClickCount++ <= maxClickCount;
}
}
}