Movement WORKS YAY

This commit is contained in:
ThomasCharester committed 2026-10-23 00:57:36 +03:00
1 parent 7098d938a7
commit 739d1f0374
68 files changed
+70968 -10846

No files matched your search

@@ -6,6 +6,6 @@ namespace Code.OfficeGame.BattleMode.Actions
{
public bool Finished { get; protected set; }
public abstract void Tick(float tickDelta);
public abstract UniTask DecideAction();
public abstract UniTask<bool> DecideAction();
}
}
@@ -1,26 +1,187 @@
using System.Threading;
using Code.Game.Gameplay.Player;
using Code.Infrastructure.Camera;
using Code.Infrastructure.Input;
using Cysharp.Threading.Tasks;
using KinematicCharacterController;
using Reflex.Attributes;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
namespace Code.OfficeGame.BattleMode.Actions
{
public class BattleActionMove : BattleAction
{
private NavMeshPath _path = new();
private Vector3 _endPosition;
public override void Tick(float tickDelta)
private CameraStateMachine _cameraStateMachine;
private IInputService _inputService;
private PlayerMovementController _playerMovementController;
private readonly NavMeshPath _path = new();
private Vector3[] _corners;
private int _currentCornerIndex;
private Vector3 _targetPosition;
private LayerMask _navMeshMask;
private const float StoppingDistance = 0.15f;
public BattleActionMove(
CameraStateMachine cameraStateMachine,
IInputService inputService,
PlayerMovementController playerMovementController)
{
KinematicCharacterSystem.Simulate(
tickDelta,
KinematicCharacterSystem.CharacterMotors,
KinematicCharacterSystem.PhysicsMovers
);
_cameraStateMachine = cameraStateMachine;
_inputService = inputService;
_playerMovementController = playerMovementController;
_navMeshMask = LayerMask.GetMask("Environment");
}
public override async UniTask DecideAction()
public override void Tick(float tickDelta)
{
_endPosition = new Vector3(0,0,0);
if (Finished) return;
if (_corners == null || _currentCornerIndex >= _corners.Length)
{
StopMovementAndFinish();
return;
}
Vector3 currentPos = _playerMovementController.Motor.TransientPosition;
while (_currentCornerIndex < _corners.Length)
{
Vector3 toCorner = _corners[_currentCornerIndex] - currentPos;
toCorner.y = 0f;
if (toCorner.sqrMagnitude <= StoppingDistance * StoppingDistance)
{
_currentCornerIndex++;
}
else
{
break;
}
}
if (_currentCornerIndex >= _corners.Length)
{
StopMovementAndFinish();
KinematicCharacterSystem.Simulate(
tickDelta,
KinematicCharacterSystem.CharacterMotors,
KinematicCharacterSystem.PhysicsMovers
);
return;
}
Vector3 targetCorner = _corners[_currentCornerIndex];
Vector3 moveDirection = targetCorner - currentPos;
moveDirection.y = 0f;
float distance = moveDirection.magnitude;
Vector3 moveNormal = distance > 0.0001f ? moveDirection / distance : Vector3.zero;
float maxStep = _playerMovementController.MaxStableMoveSpeed * tickDelta;
float inputMagnitude = (_currentCornerIndex == _corners.Length - 1 && distance < maxStep && maxStep > 0f)
? distance / maxStep
: 1f;
var aiInputs = new AICharacterInputs
{
MoveVector = moveNormal * inputMagnitude,
Look = moveNormal.sqrMagnitude > 0.0001f
? Quaternion.LookRotation(moveNormal, _playerMovementController.Motor.CharacterUp)
: _playerMovementController.Motor.TransientRotation
};
_playerMovementController.SetInputs(ref aiInputs);
KinematicCharacterSystem.Simulate(
tickDelta,
KinematicCharacterSystem.CharacterMotors,
KinematicCharacterSystem.PhysicsMovers
);
Vector3 postMovePos = _playerMovementController.Motor.TransientPosition;
Vector3 toFinal = _corners[^1] - postMovePos;
toFinal.y = 0f;
if (_currentCornerIndex >= _corners.Length - 1 && toFinal.sqrMagnitude <= StoppingDistance * StoppingDistance)
{
StopMovementAndFinish();
}
}
private void StopMovementAndFinish()
{
var emptyInputs = new AICharacterInputs
{
MoveVector = Vector3.zero,
Look = _playerMovementController.Motor.TransientRotation
};
_playerMovementController.SetInputs(ref emptyInputs);
_playerMovementController.Motor.BaseVelocity = Vector3.zero;
Finished = true;
}
private CancellationTokenSource _waitForEnterTokenSource;
private bool _positionChosen;
public override async UniTask<bool> DecideAction()
{
_waitForEnterTokenSource = new CancellationTokenSource();
_positionChosen = false;
_targetPosition = _playerMovementController.transform.position;
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Select,
SelectPosition);
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
ConfirmPosition);
await UniTask.WaitUntilCanceled(_waitForEnterTokenSource.Token).SuppressCancellationThrow();
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Select,
SelectPosition);
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
ConfirmPosition);
_waitForEnterTokenSource.Dispose();
_waitForEnterTokenSource = null;
Finished = !_positionChosen;
return _positionChosen;
}
private void ConfirmPosition(InputAction.CallbackContext input)
{
Vector3 startPos = _playerMovementController.Motor.TransientPosition;
if ((_targetPosition - startPos).sqrMagnitude > StoppingDistance * StoppingDistance
&& NavMesh.CalculatePath(startPos, _targetPosition, NavMesh.AllAreas, _path)
&& _path.corners.Length > 0)
{
_corners = _path.corners;
_currentCornerIndex = _corners.Length > 1 ? 1 : 0;
_positionChosen = true;
}
_waitForEnterTokenSource?.Cancel();
}
private void SelectPosition(InputAction.CallbackContext input)
{
var position = _cameraStateMachine.Camera.transform.position;
var direction = _cameraStateMachine.Camera.transform.forward;
var didHit = Physics.Raycast(position, direction, out RaycastHit hit, Mathf.Infinity, _navMeshMask);
if (!didHit) return;
Debug.Log($"Hit {hit.point}");
_targetPosition = hit.point;
}
}
}
@@ -11,11 +11,13 @@ namespace Code.OfficeGame.BattleMode.Actions
if (_waitFrames <= 0) Finished = true;
}
public override async UniTask DecideAction()
public override async UniTask<bool> DecideAction()
{
Finished = false;
_waitFrames = 120;
return true;
}
}
}
@@ -1,24 +1,38 @@
using System.Threading;
using Code.Game.Gameplay.Player;
using Code.Infrastructure.Camera;
using Code.Infrastructure.Input;
using Cysharp.Threading.Tasks;
using Reflex.Attributes;
using UnityEngine;
namespace Code.OfficeGame.BattleMode.Actions.Player
{
public class PlayerTimelineActor : EntityTimelineActor
{
private void Awake()
[Inject]
private void Construct(
CameraStateMachine cameraStateMachine,
IInputService inputService,
PlayerMovementController playerMovementController)
{
BattleActions.Add(BattleActionType.Wait, new BattleActionWait());
BattleActions.Add(BattleActionType.Move, new BattleActionMove(cameraStateMachine, inputService, playerMovementController));
}
public override async UniTask DecideAction(CancellationToken ct)
{
var decidedAction = BattleActionType.Wait; // T
Debug.Log("player decided to wait");
await BattleActions[decidedAction].DecideAction();
bool succeded = false;
var decidedAction = BattleActionType.Move; // T
while (!succeded || ct.IsCancellationRequested)
{
Debug.Log("player decided to move");
succeded = await BattleActions[decidedAction].DecideAction();
}
CurrentAction = BattleActions[decidedAction];
}
}
@@ -18,7 +18,9 @@ namespace Code.Infrastructure.Input
public enum BattleModeActions
{
Movement,
Watchment
Watchment,
Select,
Confirm
}
// Написать, чтобы розлин сама писала этот енам
public enum DebugActions