114 lines
3.7 KiB
C#
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);
|
|
}
|
|
}
|
|
} |