156 lines
6.0 KiB
C#
156 lines
6.0 KiB
C#
using System;
|
|
using System.Threading;
|
|
using Code.Infrastructure.Camera;
|
|
using Code.Infrastructure.Input;
|
|
using Code.OfficeGame.BattleMode.Actions.Player;
|
|
using Code.OfficeGame.BattleMode.Marker;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
namespace Code.OfficeGame.BattleMode.Actions.Deciders
|
|
{
|
|
public class RotationBattleActionDecider: BattleActionDecider
|
|
{
|
|
private CameraStateMachine _cameraStateMachine;
|
|
private IInputService _inputService;
|
|
|
|
private Quaternion _targetRotation;
|
|
|
|
private LayerMask _navMeshMask;
|
|
|
|
public RotationBattleActionDecider(
|
|
CameraStateMachine cameraStateMachine,
|
|
IInputService inputService,
|
|
MarkerManager markerManager)
|
|
{
|
|
_markerManager = markerManager;
|
|
_cameraStateMachine = cameraStateMachine;
|
|
_inputService = inputService;
|
|
_navMeshMask = LayerMask.GetMask("Environment");
|
|
}
|
|
|
|
private CancellationTokenSource _waitForEnterTokenSource;
|
|
private BattleActionDecisionResultCode _decisionResultCode;
|
|
|
|
public override DeciderType DeciderType => DeciderType.Rotation;
|
|
|
|
public override async UniTask<BattleActionDecisionResult> GetDecision()
|
|
{
|
|
if (!IsMounted) throw new Exception("Decider is not mounted"); // А почему бы и нет?
|
|
|
|
_waitForEnterTokenSource = new CancellationTokenSource();
|
|
_decisionResultCode = BattleActionDecisionResultCode.Deciding;
|
|
|
|
await UniTask.WaitUntilCanceled(_waitForEnterTokenSource.Token).SuppressCancellationThrow();
|
|
|
|
_waitForEnterTokenSource.Dispose();
|
|
_waitForEnterTokenSource = null;
|
|
|
|
return new RotationBattleActionDeciderResult()
|
|
{
|
|
ResultCode = _decisionResultCode,
|
|
Rotation = _targetRotation
|
|
};
|
|
}
|
|
|
|
public override void UnmountDecider()
|
|
{
|
|
if (!IsMounted) return;
|
|
|
|
_playerDecisionMarker.Toggle(false);
|
|
_markerManager.ReleaseMarkerInstance(_playerDecisionMarker);
|
|
_playerLockedDecisionMarker.Toggle(false);
|
|
_markerManager.ReleaseMarkerInstance(_playerLockedDecisionMarker);
|
|
|
|
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Select,
|
|
SelectRotation);
|
|
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
|
|
ConfirmRotation);
|
|
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
|
|
CancelRotation);
|
|
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Watchment,
|
|
MarkPosition);
|
|
|
|
IsMounted = false;
|
|
}
|
|
|
|
public override void MountDecider(EntityProperties entityProperties)
|
|
{
|
|
if (IsMounted) return;
|
|
|
|
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Select,
|
|
SelectRotation);
|
|
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
|
|
ConfirmRotation);
|
|
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
|
|
CancelRotation);
|
|
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Watchment,
|
|
MarkPosition);
|
|
|
|
|
|
_playerLockedDecisionMarker = _markerManager.GetMarkerInstance();
|
|
|
|
_playerDecisionMarker = _markerManager.GetMarkerInstance();
|
|
_playerDecisionMarker.Toggle(true);
|
|
|
|
_targetRotation = entityProperties.KinematicCharacterMotor.TransientRotation;
|
|
_entityPosition = entityProperties.KinematicCharacterMotor.TransientPosition;
|
|
|
|
IsMounted = true;
|
|
}
|
|
|
|
private MarkerManager _markerManager;
|
|
|
|
private void CancelRotation(InputAction.CallbackContext obj)
|
|
{
|
|
_decisionResultCode = BattleActionDecisionResultCode.CancelDecision;
|
|
_waitForEnterTokenSource?.Cancel();
|
|
}
|
|
|
|
private void ConfirmRotation(InputAction.CallbackContext input)
|
|
{
|
|
_decisionResultCode = BattleActionDecisionResultCode.Decided;
|
|
|
|
_waitForEnterTokenSource?.Cancel();
|
|
}
|
|
|
|
private RaycastHit[] _hitBuffer = new RaycastHit[1];
|
|
private PlayerDecisionMarker _playerDecisionMarker;
|
|
private PlayerDecisionMarker _playerLockedDecisionMarker;
|
|
private Vector3 _entityPosition;
|
|
|
|
private void MarkPosition(InputAction.CallbackContext input)
|
|
{
|
|
var position = _cameraStateMachine.Camera.transform.position;
|
|
var direction = _cameraStateMachine.Camera.transform.forward;
|
|
|
|
var hitCount = Physics.RaycastNonAlloc(
|
|
position,
|
|
direction,
|
|
_hitBuffer,
|
|
Mathf.Infinity,
|
|
_navMeshMask);
|
|
|
|
if (hitCount == 0
|
|
|| _entityPosition == Vector3.zero) return;
|
|
|
|
var hit = _hitBuffer[0];
|
|
|
|
var lookDirection = hit.point - _entityPosition;
|
|
_targetRotation = Quaternion.LookRotation(lookDirection.normalized, Vector3.up);
|
|
|
|
_playerDecisionMarker.transform.rotation = _targetRotation;
|
|
_playerDecisionMarker.transform.position = hit.point;
|
|
}
|
|
|
|
private void SelectRotation(InputAction.CallbackContext input)
|
|
{
|
|
_playerLockedDecisionMarker.MoveMarker(_entityPosition);
|
|
_playerLockedDecisionMarker.transform.rotation = _targetRotation;
|
|
_playerLockedDecisionMarker.Toggle(true);
|
|
|
|
_waitForEnterTokenSource?.Cancel();
|
|
}
|
|
}
|
|
} |