Skip to content

Instantly share code, notes, and snippets.

@HassakuTb
Created June 13, 2020 15:29
Show Gist options
  • Save HassakuTb/5e1c81c8212e1aeec284c6b237d09e3c to your computer and use it in GitHub Desktop.
Save HassakuTb/5e1c81c8212e1aeec284c6b237d09e3c to your computer and use it in GitHub Desktop.
ヒットストップ
using Cysharp.Threading.Tasks;
using UnityEngine;
/// <summary>
/// アクタークラス
/// </summary>
[RequireComponent(typeof(HitStunHandler))]
public class Actor : MonoBehaviour
{
/// <summary>
/// ヒットストップハンドラ
/// </summary>
private HitStunHandler hitStunHandler;
/// <summary>
/// エフェクトオブジェクトのprefab
/// </summary>
[SerializeField] private GameObject effectPrefab;
/// <summary>
/// エフェクトオブジェクトを格納するtransform
/// </summary>
[SerializeField] private Transform effectContainer;
/// <summary>
/// ヒットストップの時間(sec)
/// </summary>
[SerializeField] private float hitStunDuration;
/// <summary>
/// ヒットストップさせるかどうか
/// true: させる false: させない
/// </summary>
[SerializeField] private bool enableHitStun;
/// <summary>
///
/// </summary>
private void Awake()
{
hitStunHandler = GetComponent<HitStunHandler>();
}
/// <summary>
/// 攻撃が命中したとき、ダメージ側から呼び出される
/// </summary>
/// <param name="target">ダメージ側</param>
/// <returns></returns>
public async UniTask OnHitAttack(Transform target)
{
GameObject effect = Instantiate(effectPrefab, effectContainer);
effect.transform.position = target.position;
if (enableHitStun)
{
await hitStunHandler.DoHitStun(hitStunDuration);
}
}
}
using UnityEngine;
/// <summary>
/// 時間係数をアニメーションに適用するクラス
/// </summary>
public class AnimationDeltaTimeApplier : MonoBehaviour
{
/// <summary>
/// 対象のAnimator
/// </summary>
[SerializeField] private Animator targetAnimator;
/// <summary>
/// 時間係数を制御するインスタンス
/// </summary>
private TimeFactorController TimeFactorController
=> GetComponentInParent<TimeFactorController>();
/// <summary>
///
/// </summary>
private void Update()
{
targetAnimator.speed = TimeFactorController.ActualTimeScale;
}
}
using Cysharp.Threading.Tasks;
using System;
using System.Threading;
using UnityEngine;
/// <summary>
/// オブジェクトをヒットストップさせるコンポーネント
/// </summary>
public class HitStunHandler : MonoBehaviour
{
/// <summary>
/// キャンセルトークンソース
/// </summary>
private CancellationTokenSource tokenSource;
/// <summary>
/// ヒットストップ前の時間係数(リストア用)
/// </summary>
private float prevTimeFactor = 1f;
/// <summary>
/// 時間係数を制御するインスタンス
/// </summary>
private TimeFactorController timeFactorController;
/// <summary>
///
/// </summary>
private void Awake()
{
timeFactorController = GetComponent<TimeFactorController>();
if (timeFactorController == null)
{
timeFactorController = gameObject.AddComponent<TimeFactorController>();
}
}
/// <summary>
/// ヒットストップさせる
/// </summary>
/// <param name="duration">止める時間(sec)</param>
/// <returns></returns>
public async UniTask DoHitStun(float duration)
{
StartHitStun();
tokenSource = new CancellationTokenSource();
await UniTask.Delay(
TimeSpan.FromSeconds(duration),
ignoreTimeScale: true,
cancellationToken:tokenSource.Token);
tokenSource = null;
StopHitStun();
}
/// <summary>
/// ヒットストップを始める
/// </summary>
private void StartHitStun()
{
prevTimeFactor = timeFactorController.TimeFactor;
timeFactorController.TimeFactor = 0f;
}
/// <summary>
/// ヒットストップを止める
/// </summary>
private void StopHitStun()
{
timeFactorController.TimeFactor = prevTimeFactor;
}
/// <summary>
/// ヒットストップを解除する
/// </summary>
public void Resume()
{
if (tokenSource != null)
{
tokenSource.Cancel();
}
StopHitStun();
}
}
using UnityEngine;
/// <summary>
/// 時間係数をワンショットパーティクルに適用するクラス
/// </summary>
[RequireComponent(typeof(ParticleSystem))]
public class OneShotParticleTimeFactorApplier : MonoBehaviour
{
/// <summary>
/// 対象のパーティクルシステム
/// </summary>
private ParticleSystem particle;
/// <summary>
/// 時間係数を制御するインスタンス
/// </summary>
private TimeFactorController timeFactorController;
/// <summary>
/// エフェクトの開始時間(sec)
/// </summary>
[SerializeField] private float effectTimeOffset;
/// <summary>
///
/// </summary>
private void Awake()
{
particle = GetComponent<ParticleSystem>();
timeFactorController = GetComponentInParent<TimeFactorController>();
}
/// <summary>
///
/// </summary>
private void Start()
{
particle.Simulate(
effectTimeOffset,
withChildren: true,
restart: false,
fixedTimeStep: false);
}
/// <summary>
///
/// </summary>
private void Update()
{
particle.Simulate(
timeFactorController.ActualDeltaTime,
withChildren: true,
restart: false,
fixedTimeStep: false);
}
}
using UnityEngine;
/// <summary>
/// 時間係数を制御するクラス
/// </summary>
public class TimeFactorController : MonoBehaviour
{
/// <summary>
/// 時間係数
/// </summary>
public float TimeFactor { get; set; } = 1f;
/// <summary>
/// 1フレームあたりの時間(sec)
/// </summary>
public float ActualDeltaTime { get; private set; }
/// <summary>
/// タイムスケール
/// </summary>
public float ActualTimeScale { get; private set; }
/// <summary>
///
/// </summary>
private void Update()
{
ActualDeltaTime = Time.deltaTime * TimeFactor;
ActualTimeScale = Time.timeScale * TimeFactor;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment