HoloCop in progress
This commit is contained in:
1 parent
2697212f05
commit
430b250075
79 files changed
+120745
-45077
No files matched your search
@@ -1,35 +1,77 @@
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Code.Infrastructure.Input;
|
||||
using Code.Infrastructure.Utils;
|
||||
using Code.OfficeGame.BattleMode.Actions.HoloCopy;
|
||||
using Code.OfficeGame.BattleMode.HitBoxes;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Reflex.Attributes;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Code.OfficeGame.BattleMode.Actions.Attacks
|
||||
{
|
||||
public class BattleActionPlayerAttackMMA : BattleAction
|
||||
{
|
||||
private Animator _animator;
|
||||
[SerializeField] private HoloCop holoCop;
|
||||
[SerializeField] private Animator animator;
|
||||
private EntityHitBoxes _entityHitBoxes;
|
||||
private AttackActionConfig _attackData;
|
||||
public int EntryStateHash => Animator.StringToHash("WalkBlend");
|
||||
|
||||
private int _currentFrame;
|
||||
|
||||
private IInputService _inputService;
|
||||
private CancellationTokenSource _waitForEnterTokenSource;
|
||||
private BattleActionDecisionResultCode _decisionResultCode;
|
||||
|
||||
[Inject]
|
||||
public void Construct(MultipleConfig<BattleActionParameters> attackData)
|
||||
public void Construct(MultipleConfig<BattleActionParameters> attackData, IInputService inputService)
|
||||
{
|
||||
_animator = GetComponentInChildren<Animator>();
|
||||
_inputService = inputService;
|
||||
|
||||
_entityHitBoxes = GetComponent<EntityHitBoxes>();
|
||||
|
||||
_attackData = (AttackActionConfig) attackData.Configs.SingleOrDefault(x=>x.ActionType == ActionType);
|
||||
}
|
||||
|
||||
|
||||
public override async UniTask<BattleActionDecisionResult> DecideAction()
|
||||
{
|
||||
_currentFrame = 0;
|
||||
Finished = false;
|
||||
|
||||
_waitForEnterTokenSource = new CancellationTokenSource();
|
||||
_decisionResultCode = BattleActionDecisionResultCode.CancelDecision;
|
||||
|
||||
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
|
||||
ConfirmAttack);
|
||||
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
|
||||
CancelAttack);
|
||||
|
||||
return new() { ResultCode = BattleActionDecisionResultCode.Decided, FrameDuration = _attackData.TotalFrames};
|
||||
holoCop.Simulate(TickHoloCopy, _waitForEnterTokenSource.Token).Forget();
|
||||
|
||||
await UniTask.WaitUntilCanceled(_waitForEnterTokenSource.Token).SuppressCancellationThrow();
|
||||
|
||||
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
|
||||
ConfirmAttack);
|
||||
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
|
||||
CancelAttack);
|
||||
|
||||
_currentFrame = 0;
|
||||
|
||||
return new() { ResultCode = _decisionResultCode, FrameDuration = _attackData.TotalFrames};
|
||||
}
|
||||
|
||||
private void CancelAttack(InputAction.CallbackContext obj)
|
||||
{
|
||||
_decisionResultCode = BattleActionDecisionResultCode.CancelDecision;
|
||||
_waitForEnterTokenSource?.Cancel();
|
||||
}
|
||||
|
||||
private void ConfirmAttack(InputAction.CallbackContext obj)
|
||||
{
|
||||
_decisionResultCode = BattleActionDecisionResultCode.Decided;
|
||||
_waitForEnterTokenSource?.Cancel();
|
||||
}
|
||||
|
||||
public override BattleActionType ActionType => BattleActionType.PlayerAttackMMA;
|
||||
@@ -40,7 +82,7 @@ namespace Code.OfficeGame.BattleMode.Actions.Attacks
|
||||
|
||||
if (_currentFrame == 0)
|
||||
{
|
||||
_animator.Play(_attackData.StateHash, 0, 0f);
|
||||
animator.Play(_attackData.StateHash, 0, 0f);
|
||||
}
|
||||
|
||||
_currentFrame++;
|
||||
@@ -70,9 +112,23 @@ namespace Code.OfficeGame.BattleMode.Actions.Attacks
|
||||
|
||||
public void CompleteOrInterruptAction()
|
||||
{
|
||||
_animator.Play(EntryStateHash, 0, 0f); // Создать None State и кинуть эту штуку туда
|
||||
animator.Play(EntryStateHash, 0, 0f); // Создать None State и кинуть эту штуку туда
|
||||
_entityHitBoxes.DisableAllHitboxes();
|
||||
Finished = true;
|
||||
}
|
||||
|
||||
// HoloCopy
|
||||
|
||||
private bool TickHoloCopy(HoloCop holoCop, float tickDelta)
|
||||
{
|
||||
if (_currentFrame == 0)
|
||||
{
|
||||
holoCop.Animator.Play(_attackData.StateHash, 0, 0f);
|
||||
}
|
||||
|
||||
_currentFrame++;
|
||||
|
||||
return _currentFrame >= _attackData.TotalFrames;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using System.Threading;
|
||||
using Code.Game.Gameplay.Player;
|
||||
using Code.Infrastructure.Camera;
|
||||
using Code.Infrastructure.Input;
|
||||
using Code.OfficeGame.BattleMode.Actions.Player;
|
||||
using Code.OfficeGame.BattleMode.Timeline;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using KinematicCharacterController;
|
||||
@@ -30,8 +31,10 @@ namespace Code.OfficeGame.BattleMode.Actions
|
||||
[Inject]
|
||||
public void Construct(
|
||||
CameraStateMachine cameraStateMachine,
|
||||
IInputService inputService)
|
||||
IInputService inputService,
|
||||
PlayerDecisionMarker playerDecisionMarker)
|
||||
{
|
||||
_playerDecisionMarker = playerDecisionMarker;
|
||||
_cameraStateMachine = cameraStateMachine;
|
||||
_inputService = inputService;
|
||||
_movementController = GetComponent<MovementController>();
|
||||
@@ -87,7 +90,8 @@ namespace Code.OfficeGame.BattleMode.Actions
|
||||
float inputMagnitude = (_currentCornerIndex == _corners.Length - 1 && distance < maxStep && maxStep > 0f)
|
||||
? distance / maxStep
|
||||
: 1f;
|
||||
|
||||
|
||||
// TODO Для последнего кадра должен быть особый Look совпадающий с маркером
|
||||
var aiInputs = new AICharacterInputs
|
||||
{
|
||||
MoveVector = moveNormal * inputMagnitude,
|
||||
@@ -116,6 +120,7 @@ namespace Code.OfficeGame.BattleMode.Actions
|
||||
|
||||
private void StopMovementAndFinish()
|
||||
{
|
||||
Debug.Log("MovementFinished");
|
||||
var emptyInputs = new AICharacterInputs
|
||||
{
|
||||
MoveVector = Vector3.zero,
|
||||
@@ -142,15 +147,23 @@ namespace Code.OfficeGame.BattleMode.Actions
|
||||
ConfirmPosition);
|
||||
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
|
||||
CancelPosition);
|
||||
_inputService.BindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Watchment,
|
||||
MarkPosition);
|
||||
|
||||
_playerDecisionMarker.Toggle(true);
|
||||
|
||||
await UniTask.WaitUntilCanceled(_waitForEnterTokenSource.Token).SuppressCancellationThrow();
|
||||
|
||||
_playerDecisionMarker.Toggle(false);
|
||||
|
||||
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Select,
|
||||
SelectPosition);
|
||||
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Confirm,
|
||||
ConfirmPosition);
|
||||
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Cancel,
|
||||
CancelPosition);
|
||||
_inputService.UnbindActionPerformed((int)ActionMappings.BattleMode, (int)BattleModeActions.Watchment,
|
||||
MarkPosition);
|
||||
|
||||
_waitForEnterTokenSource.Dispose();
|
||||
_waitForEnterTokenSource = null;
|
||||
@@ -163,6 +176,7 @@ namespace Code.OfficeGame.BattleMode.Actions
|
||||
public override BattleActionType ActionType => BattleActionType.Move;
|
||||
|
||||
private int _totalFrames;
|
||||
private PlayerDecisionMarker _playerDecisionMarker;
|
||||
|
||||
private void CancelPosition(InputAction.CallbackContext obj)
|
||||
{
|
||||
@@ -217,18 +231,37 @@ namespace Code.OfficeGame.BattleMode.Actions
|
||||
// Округляем вверх, так как последний неполный шаг тоже занимает 1 целый кадр
|
||||
return Mathf.CeilToInt(effectiveDistance / stepPerFrame);
|
||||
}
|
||||
private void SelectPosition(InputAction.CallbackContext input)
|
||||
|
||||
private RaycastHit[] _hitBuffer = new RaycastHit[1];
|
||||
private Vector3 _lastViewedPosition;
|
||||
private void MarkPosition(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);
|
||||
var hitCount = Physics.RaycastNonAlloc(position, direction, _hitBuffer, Mathf.Infinity, _navMeshMask);
|
||||
|
||||
if (!didHit) return;
|
||||
if (hitCount == 0) return;
|
||||
|
||||
Debug.Log($"Hit {hit.point}");
|
||||
var hit = _hitBuffer[0];
|
||||
|
||||
_playerDecisionMarker.MoveMarker(hit.point);
|
||||
|
||||
_targetPosition = hit.point;
|
||||
_lastViewedPosition = hit.point;
|
||||
}
|
||||
|
||||
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 {_lastViewedPosition}");
|
||||
|
||||
_targetPosition = _lastViewedPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb857a2eae284b31b2eb19ac4abfcaa7
|
||||
timeCreated: 1793141973
|
||||
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Code.Game.Gameplay.Player;
|
||||
using Code.OfficeGame.BattleMode.Timeline;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using KinematicCharacterController;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Code.OfficeGame.BattleMode.Actions.HoloCopy
|
||||
{
|
||||
public class HoloCop : MonoBehaviour
|
||||
{
|
||||
private Func<HoloCop, float, bool> _action;
|
||||
|
||||
[SerializeField] private MovementController movementController;
|
||||
[SerializeField] private KinematicCharacterMotor motor;
|
||||
[SerializeField] private Animator animator;
|
||||
|
||||
public MovementController Controller => movementController;
|
||||
public Animator Animator => animator;
|
||||
|
||||
private Vector3 _initialPosition;
|
||||
private Quaternion _initialRotation;
|
||||
private int _initialAnimationState;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
animator = GetComponentInChildren<Animator>();
|
||||
movementController = GetComponent<MovementController>();
|
||||
motor = GetComponent<KinematicCharacterMotor>();
|
||||
}
|
||||
|
||||
private void Snapshot()
|
||||
{
|
||||
_initialPosition = motor.transform.position;
|
||||
_initialRotation = motor.transform.rotation;
|
||||
|
||||
_initialAnimationState = animator.GetCurrentAnimatorStateInfo(0).shortNameHash;
|
||||
}
|
||||
|
||||
private void ReturnToSnapshot()
|
||||
{
|
||||
motor.SetPositionAndRotation(_initialPosition, _initialRotation);
|
||||
|
||||
animator.Play(_initialAnimationState, 0);
|
||||
}
|
||||
|
||||
public async UniTask Simulate(Func<HoloCop, float, bool> action, CancellationToken ctx)
|
||||
{
|
||||
_action = action;
|
||||
float accumulator = 0f;
|
||||
|
||||
Snapshot();
|
||||
|
||||
try
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
|
||||
while (!ctx.IsCancellationRequested)
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.Update, ctx);
|
||||
|
||||
accumulator += Time.unscaledDeltaTime;
|
||||
|
||||
while (accumulator >= BattleTimeline.TickDelta)
|
||||
{
|
||||
accumulator -= BattleTimeline.TickDelta;
|
||||
|
||||
if (_action == null) return;
|
||||
|
||||
bool result = _action(this, BattleTimeline.TickDelta);
|
||||
|
||||
animator.Update(BattleTimeline.TickDelta);
|
||||
|
||||
Physics.Simulate(BattleTimeline.TickDelta);
|
||||
Physics.SyncTransforms();
|
||||
|
||||
if (result) ReturnToSnapshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReturnToSnapshot();
|
||||
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4067e559c4d4556a335b4c507f9702f
|
||||
timeCreated: 1793142036
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Threading;
|
||||
using Code.Game.OfficeGame.BattleMode;
|
||||
using Code.Infrastructure.Camera;
|
||||
using Code.OfficeGame.BattleMode.UI;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Reflex.Attributes;
|
||||
@@ -9,6 +11,7 @@ namespace Code.OfficeGame.BattleMode.Actions.Player
|
||||
public class PlayerControlledTimelineActor : EntityTimelineActor
|
||||
{
|
||||
[Inject] private BattleActionDecisionPanel _battleActionDecisionPanel;
|
||||
[Inject] private CameraStateMachine _cameraStateMachine;
|
||||
|
||||
public override async UniTask DecideAction(CancellationToken ctx)
|
||||
{
|
||||
@@ -22,6 +25,8 @@ namespace Code.OfficeGame.BattleMode.Actions.Player
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.Confined;
|
||||
|
||||
((CameraBattleModeState)_cameraStateMachine.CurrentBaseState).battleDeciding = true;
|
||||
|
||||
await _battleActionDecisionPanel.Open(ctx);
|
||||
|
||||
decidedAction = await _battleActionDecisionPanel.GetDecision(ctx);
|
||||
@@ -31,6 +36,8 @@ namespace Code.OfficeGame.BattleMode.Actions.Player
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
|
||||
((CameraBattleModeState)_cameraStateMachine.CurrentBaseState).battleDeciding = false;
|
||||
|
||||
await _battleActionDecisionPanel.Close(ctx);
|
||||
|
||||
decision = await BattleActions[decidedAction].DecideAction();
|
||||
@@ -42,6 +49,7 @@ namespace Code.OfficeGame.BattleMode.Actions.Player
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetCurrentAction(BattleActions[decidedAction], decision.FrameDuration);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Code.OfficeGame.BattleMode.Actions.Player
|
||||
{
|
||||
public class PlayerDecisionMarker : MonoBehaviour
|
||||
{
|
||||
public bool locked;
|
||||
public void Toggle(bool onOff)
|
||||
{
|
||||
locked = false;
|
||||
gameObject.SetActive(onOff);
|
||||
}
|
||||
|
||||
public void MoveMarker(Vector3 position)
|
||||
{
|
||||
if (locked) return;
|
||||
|
||||
transform.position = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6dcb7d02c6a54c0a9758279c38260aef
|
||||
timeCreated: 1793143524
|
||||
@@ -0,0 +1,13 @@
|
||||
using Code.Infrastructure.Generators;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Code.OfficeGame.BattleMode.Actions.Player
|
||||
{
|
||||
// TODO Эта штука просто загружена вместе с конфигом
|
||||
[Config("Configs/PlayerDecisionMarker")]
|
||||
[CreateAssetMenu(fileName = "PlayerDecisionMarkerConfig", menuName = "Configs/PlayerDecisionMarker")]
|
||||
public class PlayerDecisionMarkerConfig : ScriptableObject
|
||||
{
|
||||
public PlayerDecisionMarker PlayerDecisionMarkerPrefab;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ae7c4b6492048df8d5bbb43e7909af0
|
||||
timeCreated: 1793143622
|
||||
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using Code.Infrastructure.Camera;
|
||||
using Code.Infrastructure.Camera.CameraStates;
|
||||
using Code.Infrastructure.Input;
|
||||
@@ -11,15 +10,18 @@ namespace Code.Game.OfficeGame.BattleMode
|
||||
[Infrastructure.Generators.State(typeof(CameraMode), typeof(CameraStateMachineContext), ManualInherit = true)]
|
||||
public partial class CameraBattleModeState : BaseCameraState
|
||||
{
|
||||
public bool battleDeciding = false;
|
||||
private bool _rightClickHold = false;
|
||||
|
||||
private Vector2 _mouseDelta;
|
||||
private Vector2 _rotation = Vector2.zero;
|
||||
private Vector2 _movement;
|
||||
private float _verticalMovement; // Если захотите добавить Space / Ctrl как в Minecraft
|
||||
|
||||
[Header("Look Settings")] private float _sensitivityX = 0.1f;
|
||||
private float _sensitivityX = 0.1f;
|
||||
private float _sensitivityY = 0.1f;
|
||||
|
||||
[Header("Spectator Flight Settings")] private float _moveSpeed = 12f;
|
||||
private float _moveSpeed = 12f;
|
||||
private float _cameraRadius = 0.25f; // Должен быть больше nearClipPlane камеры (обычно 0.05 - 0.1)
|
||||
private LayerMask _obstacleMask = ~0; // По умолчанию все слои (настройте, исключив триггеры/юнитов)
|
||||
|
||||
@@ -55,6 +57,15 @@ namespace Code.Game.OfficeGame.BattleMode
|
||||
(int)ActionMappings.BattleMode,
|
||||
(int)BattleModeActions.Watchment,
|
||||
LookCancelled);
|
||||
|
||||
Context.InputService.BindActionPerformed(
|
||||
(int)ActionMappings.BattleMode,
|
||||
(int)BattleModeActions.RightClick,
|
||||
RightClickPerformed);
|
||||
Context.InputService.BindActionCancelled(
|
||||
(int)ActionMappings.BattleMode,
|
||||
(int)BattleModeActions.RightClick,
|
||||
RightClickCancelled);
|
||||
|
||||
var camTransform = Context.cameraLoadedData.Camera.transform;
|
||||
|
||||
@@ -102,6 +113,9 @@ namespace Code.Game.OfficeGame.BattleMode
|
||||
|
||||
private void LookCancelled(InputAction.CallbackContext obj) => _mouseDelta = Vector2.zero;
|
||||
private void LookPerformed(InputAction.CallbackContext obj) => _mouseDelta = obj.ReadValue<Vector2>();
|
||||
|
||||
private void RightClickCancelled(InputAction.CallbackContext obj) => _rightClickHold = false;
|
||||
private void RightClickPerformed(InputAction.CallbackContext obj) => _rightClickHold = true;
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
@@ -112,15 +126,15 @@ namespace Code.Game.OfficeGame.BattleMode
|
||||
var camTransform = Context.cameraLoadedData.Camera.transform;
|
||||
float dt = Time.unscaledDeltaTime;
|
||||
|
||||
// --- 1. СВОБОДНЫЙ ОБЗОР ОТ ПЕРВОГО ЛИЦА (Yaw + Pitch) ---
|
||||
_rotation.x += _mouseDelta.x * _sensitivityX;
|
||||
_rotation.y -= _mouseDelta.y * _sensitivityY;
|
||||
_rotation.y = Mathf.Clamp(_rotation.y, -89.9f, 89.9f);
|
||||
if (!(battleDeciding && !_rightClickHold))
|
||||
{
|
||||
_rotation.x += _mouseDelta.x * _sensitivityX;
|
||||
_rotation.y -= _mouseDelta.y * _sensitivityY;
|
||||
_rotation.y = Mathf.Clamp(_rotation.y, -89.9f, 89.9f);
|
||||
|
||||
// Используем мировое вращение, чтобы камера всегда держала горизонт ровно (без завала Roll)
|
||||
camTransform.rotation = Quaternion.Euler(_rotation.y, _rotation.x, 0f);
|
||||
|
||||
// --- 2. ВЕКТОР ПОЛЁТА КАК В CS / MINECRAFT SPECTATOR ---
|
||||
camTransform.rotation = Quaternion.Euler(_rotation.y, _rotation.x, 0f);
|
||||
}
|
||||
|
||||
Vector3 wishDir = camTransform.forward * _movement.y + camTransform.right * _movement.x;
|
||||
|
||||
// Если добавите кнопки вверх/вниз (Space/Ctrl), раскомментируйте:
|
||||
@@ -131,10 +145,8 @@ namespace Code.Game.OfficeGame.BattleMode
|
||||
|
||||
Vector3 currentPos = camTransform.position;
|
||||
|
||||
// --- 3. ВЫТАЛКИВАНИЕ (Если камера начала кадр внутри стены или двери) ---
|
||||
currentPos = Depenetrate(currentPos);
|
||||
|
||||
// --- 4. ДВИЖЕНИЕ И СКОЛЬЖЕНИЕ ПО СТЕНАМ И УГЛАМ ---
|
||||
if (wishDir.sqrMagnitude > 0.0001f)
|
||||
{
|
||||
Vector3 displacement = wishDir * (_moveSpeed * dt);
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace Code.OfficeGame.BattleMode.Timeline
|
||||
_entities = entities;
|
||||
_currentBattleFrame.Value = 0;
|
||||
|
||||
// Контейнер подписок на время текущего боя (автоматически очистится при выходе из метода)
|
||||
_battleSubscriptions = new DisposableBag();
|
||||
|
||||
try
|
||||
@@ -42,7 +41,6 @@ namespace Code.OfficeGame.BattleMode.Timeline
|
||||
entity.OnActionSet
|
||||
.Subscribe(action =>
|
||||
{
|
||||
// Переводим длительность действия в абсолютный кадр окончания на таймлайне
|
||||
action.Frame += _currentBattleFrame.Value;
|
||||
_timelinePanel.SetAction(action);
|
||||
})
|
||||
@@ -72,14 +70,14 @@ namespace Code.OfficeGame.BattleMode.Timeline
|
||||
}
|
||||
}
|
||||
|
||||
private async UniTask<List<EntityTimelineActor>> PlayTimelineUntilPause(CancellationToken ct)
|
||||
private async UniTask<List<EntityTimelineActor>> PlayTimelineUntilPause(CancellationToken ctx)
|
||||
{
|
||||
float accumulator = 0f;
|
||||
var readyEntities = new List<EntityTimelineActor>();
|
||||
|
||||
while (readyEntities.Count == 0 && !ct.IsCancellationRequested)
|
||||
while (readyEntities.Count == 0 && !ctx.IsCancellationRequested)
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.Update, ct);
|
||||
await UniTask.Yield(PlayerLoopTiming.Update, ctx);
|
||||
|
||||
accumulator += Time.unscaledDeltaTime;
|
||||
|
||||
|
||||
Reference in new issue
Block a user