Files
Hasebe/Assets/Code/D/Player/PlayerDetailMaskDrawer.cs
T
2026-09-20 15:26:03 +03:00

114 lines
3.7 KiB
C#

using Code.D.Cleaning;
using Code.D.Player;
using Code.Infrastructure.Camera;
using Code.Infrastructure.Input;
using Cysharp.Threading.Tasks;
using R3;
using Reflex.Attributes;
using UnityEngine;
using UnityEngine.InputSystem;
namespace Code.Game.Gameplay.Player
{
public class PlayerDetailMaskDrawer : MonoBehaviour
{
private IInputService _inputService;
private Transform _cameraTransform;
private bool _cleaning, _cleaningUnder;
private LayerMask _layerMask;
private TagHandle _surfaceTag;
private CleanableSurface _lastCleaned;
[SerializeField] private float cleaningDistance = 5f;
[SerializeField] private PlayerEquipment playerEquipment;
private void Awake()
{
_surfaceTag = TagHandle.GetExistingTag("CleanableSurface");
_layerMask = LayerMask.GetMask("Cleanable");
GetComponent<PlayerMovementController>().IsSliding.Subscribe(SlideToggle).AddTo(destroyCancellationToken);
}
[Inject]
private void Construct(IInputService inputService, CameraStateMachine cameraStateMachine)
{
_cameraTransform = cameraStateMachine.Camera.transform;
_inputService = inputService;
_inputService.BindActionPerformed((int)ActionMappings.Cleaning, (int)CleaningActions.Clean, DrawPerformed);
_inputService.BindActionCancelled((int)ActionMappings.Cleaning, (int)CleaningActions.Clean, DrawCancelled);
}
private void SlideToggle(bool isSliding) => _cleaningUnder = isSliding;
private void DrawPerformed(InputAction.CallbackContext obj) => _cleaning = true;
private void DrawCancelled(InputAction.CallbackContext obj) => _cleaning = false;
private void FixedUpdate()
{
if (_cleaning) CleanInFront();
if (_cleaningUnder) CleanUnder();
}
private void CleanUnder()
{
if (!Physics.Raycast(
_cameraTransform.position,
-transform.up,
out var info,
5f,
layerMask: _layerMask)) return;
if (info.collider.CompareTag(_surfaceTag))
CleanSurface(info);
}
private void CleanInFront()
{
if (!Physics.Raycast(
_cameraTransform.position,
_cameraTransform.forward,
out var info,
cleaningDistance,
layerMask: _layerMask)) return;
if (info.collider.CompareTag(_surfaceTag))
CleanSurface(info);
else
CleanAsset(info);
}
private void CleanAsset(RaycastHit info)
{
var cleanable = info.collider.GetComponent<CleanableAsset>();
cleanable.Clean();
}
private void CleanSurface(RaycastHit info)
{
CleanableSurface cleanable;
if (_lastCleaned is not null && info.collider.GetEntityId() == _lastCleaned.GetEntityId())
cleanable = _lastCleaned;
else
{
cleanable = info.collider.GetComponent<CleanableSurface>();
_lastCleaned = cleanable;
}
cleanable.Clean(info, playerEquipment.CurrentTool.Use(), _cameraTransform);
}
private void OnDestroy()
{
_inputService.UnbindActionPerformed((int)ActionMappings.Cleaning, (int)CleaningActions.Clean,
DrawPerformed);
_inputService.UnbindActionCancelled((int)ActionMappings.Cleaning, (int)CleaningActions.Clean,
DrawCancelled);
}
}
}