Files
Cielonos/Assets/Scripts/MainGame/Effects/Feedbacks/Actions/CameraPositionShakeAction.cs
SoulliesOfficial 41140a2017 新Feedback系统
2026-04-12 02:11:15 -04:00

103 lines
3.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using MoreMountains.Feedbacks;
using Sirenix.OdinInspector;
using SLSUtilities.Feedback;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 摄像机位移震动反馈,通过 MMCinemachinePositionShakeEvent 触发现有的 Shaker。
/// Shaker 负责处理多个震动的叠加混合。
/// </summary>
[Serializable]
public class CameraPositionShakeAction : FeedbackActionBase
{
public override string DisplayName => "Camera Position Shake";
/// <summary>
/// 震动曲线,定义震动强度随时间的变化。
/// </summary>
[Title("Position Shake")]
[LabelText("Shake Curve")]
public AnimationCurve shakeCurve = new AnimationCurve(
new Keyframe(0f, 0f),
new Keyframe(0.2f, 1f),
new Keyframe(1f, 0f)
);
/// <summary>
/// 最大位移振幅(本地空间)。
/// </summary>
[LabelText("Amplitude")]
public Vector3 positionAmplitude = new Vector3(0.5f, 0.5f, 0f);
/// <summary>
/// 方向影响设置。
/// </summary>
[Title("Direction")]
public CameraDirectionSettings directionSettings = new CameraDirectionSettings();
/// <summary>
/// 距离衰减:根据摄像机与 owner 的距离衰减震动强度。
/// </summary>
[Title("Distance Attenuation")]
[LabelText("Use Attenuation")]
public bool useAttenuation;
/// <summary>
/// 全强度的最大距离。
/// </summary>
[ShowIf("useAttenuation")]
[LabelText("Attenuation Range")]
public float attenuationRange = 50f;
/// <summary>
/// 距离-强度衰减曲线0=近处/全强度1=远处/无强度)。
/// </summary>
[ShowIf("useAttenuation")]
[LabelText("Attenuation Curve")]
public AnimationCurve attenuationCurve = new AnimationCurve(
new Keyframe(0f, 1f),
new Keyframe(1f, 0f)
);
public override void OnStart(FeedbackContext context)
{
Vector3 finalAmplitude = directionSettings.TransformAmplitude(positionAmplitude, context.owner);
float intensityMultiplier = ComputeAttenuation(context);
MMCinemachinePositionShakeEvent.Trigger(
null,
shakeCurve,
context.duration,
finalAmplitude,
intensityMultiplier
);
}
public override void OnInterrupt(FeedbackContext context)
{
MMCinemachinePositionShakeEvent.Trigger(
null, shakeCurve, 0f, Vector3.zero, 0f,
stop: true
);
}
/// <summary>
/// 计算距离衰减系数。
/// </summary>
private float ComputeAttenuation(FeedbackContext context)
{
if (!useAttenuation || context.owner == null) return 1f;
Camera mainCamera = Camera.main;
if (mainCamera == null) return 1f;
float distance = Vector3.Distance(context.owner.position, mainCamera.transform.position);
float normalizedDistance = Mathf.Clamp01(distance / attenuationRange);
return attenuationCurve.Evaluate(normalizedDistance);
}
}
}