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

99 lines
3.2 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.FeedbacksForThirdParty;
using Sirenix.OdinInspector;
using SLSUtilities.Feedback;
using UnityEngine;
namespace Cielonos.MainGame.Effects.Feedback
{
/// <summary>
/// 摄像机旋转震动反馈,通过 MMCinemachineRotationShakeEvent 触发现有的 Shaker。
/// X/Y 作用于 FollowTarget 旋转Z 作用于 Dutch 倾斜。
/// </summary>
[Serializable]
public class CameraRotationShakeAction : FeedbackActionBase
{
public override string DisplayName => "Camera Rotation Shake";
/// <summary>
/// 震动曲线,定义震动强度随时间的变化。
/// </summary>
[Title("Rotation Shake")]
[LabelText("Shake Curve")]
public AnimationCurve shakeCurve = new AnimationCurve(
new Keyframe(0f, 0f),
new Keyframe(0.2f, 1f),
new Keyframe(1f, 0f)
);
/// <summary>
/// 最大旋转角度振幅。X/Y -> FollowTarget, Z -> Dutch。
/// </summary>
[LabelText("Rotation Amplitude")]
public Vector3 rotationAmplitude = new Vector3(2f, 2f, 5f);
/// <summary>
/// 方向影响设置。
/// </summary>
[Title("Direction")]
public CameraDirectionSettings directionSettings = new CameraDirectionSettings();
/// <summary>
/// 距离衰减。
/// </summary>
[Title("Distance Attenuation")]
[LabelText("Use Attenuation")]
public bool useAttenuation;
[ShowIf("useAttenuation")]
[LabelText("Attenuation Range")]
public float attenuationRange = 50f;
[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(rotationAmplitude, context.owner);
float intensityMultiplier = ComputeAttenuation(context);
MMCinemachineRotationShakeEvent.Trigger(
null,
shakeCurve,
context.duration,
finalAmplitude,
0f, 1f, false,
intensityMultiplier
);
}
public override void OnInterrupt(FeedbackContext context)
{
MMCinemachineRotationShakeEvent.Trigger(
null, shakeCurve, 0f, Vector3.zero,
0f, 1f, false,
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);
}
}
}