using Ichni.RhythmGame.Beatmap; using UnityEngine; namespace Ichni.RhythmGame { public class CameraShakeEffect : EffectBase { #region [效果参数] Effect Parameters public float frequency; public float amplitudeX; public float amplitudeY; public float amplitudeZ; private Transform _cameraTransform; #endregion #region [初始化] Initialization public CameraShakeEffect(float effectTime, float frequency, float amplitudeX, float amplitudeY, float amplitudeZ) : base(effectTime) { this.effectTime = effectTime; this.frequency = frequency; // 数值越大抖动越跳跃 this.amplitudeX = amplitudeX; this.amplitudeY = amplitudeY; this.amplitudeZ = amplitudeZ; } #endregion #region [效果逻辑覆盖] Effect Pattern Overrides public override void PreExecute() { // 抓取摄像机 Transform if (_cameraTransform == null) { _cameraTransform = GameManager.Instance.cameraManager.gameCamera.cam.transform; } } public override void Execute() { if (_cameraTransform != null) { // 一套基于柏林噪声和音乐进展时间的稳固伪随机位移计算 // 因为基于 effectProgressPercent 产生,所以录像回退或者暂停时,位置百分百受控复现 float timeFactor = effectProgressPercent * frequency; // 随着时间推移,让震动平滑消退 (1.0 -> 0.0) float dampening = 1.0f - effectProgressPercent; float offsetX = (Mathf.PerlinNoise(timeFactor, 0) - 0.5f) * 2f * amplitudeX * dampening; float offsetY = (Mathf.PerlinNoise(0, timeFactor) - 0.5f) * 2f * amplitudeY * dampening; float offsetZ = (Mathf.PerlinNoise(timeFactor, timeFactor) - 0.5f) * 2f * amplitudeZ * dampening; // 这次应用仅在局部空间偏移,非常干净轻量 _cameraTransform.localPosition = new Vector3(offsetX, offsetY, offsetZ); } } public override void Adjust() { ResetEffect(); } public override void Recover() { ResetEffect(); } public override void Disrupt() { ResetEffect(); } private void ResetEffect() { if (_cameraTransform != null) { _cameraTransform.localPosition = Vector3.zero; } } #endregion } }