91 lines
2.7 KiB
C#
91 lines
2.7 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
} |