Files
bansonic_beta_main/Assets/scripts/gamePlay_gameplay/effectEventController.cs
T

345 lines
11 KiB
C#

using SmoothShakeFree;
using UnityEngine;
public class effectEventController : MonoBehaviour
{
public enum CameraOffsetAxis
{
X,
Y,
Z
}
public static effectEventController Instance { get; private set; }
[Header("Multi Note Screen Shake")]
public bool enableMultiNoteScreenShake = true;
public float multiNoteScreenShakeAmplitude = 0.08f;
[Header("Camera Drift")]
public bool enableCameraDrift = false;
public Vector2 cameraDriftRange = new Vector2(0.15f, 0.08f);
public float cameraDriftSpeed = 0.3f;
[Header("Player Skill 10 Camera Offset")]
public float playerSkillCameraOffsetAmount = 0.6f;
public CameraOffsetAxis playerSkillCameraOffsetAxis = CameraOffsetAxis.Y;
[Header("Track Crash")]
[SerializeField] private TrackCrashController trackCrashController;
private Transform cachedShakeTarget;
private Transform cachedCameraDriftPivot;
private Transform cachedCameraSkillPivot;
private Vector3 cameraDriftBaseLocalPosition;
private Vector3 cameraSkillBaseLocalPosition;
private float cameraDriftSeedX;
private float cameraDriftSeedY;
private void Awake()
{
if (Instance == null)
{
Instance = this;
cameraDriftSeedX = Random.Range(0f, 1000f);
cameraDriftSeedY = Random.Range(1000f, 2000f);
CacheShakeTarget();
return;
}
if (Instance != this)
{
Destroy(gameObject);
}
}
private void OnEnable()
{
CacheShakeTarget();
ResetCameraDriftIfNeeded();
CacheTrackCrashController();
}
private void Update()
{
UpdateCameraDrift();
UpdatePlayerSkillCameraOffset();
}
private void CacheShakeTarget()
{
if (Camera.main != null)
{
cachedShakeTarget = Camera.main.transform;
PrewarmShakeComponent();
EnsureCameraDriftPivot();
EnsureCameraSkillPivot();
}
}
private void CacheTrackCrashController()
{
if (trackCrashController == null)
{
trackCrashController = SceneObjectLookupCache.FindAny<TrackCrashController>();
}
}
private void PrewarmShakeComponent()
{
if (cachedShakeTarget == null)
return;
SmoothShake shake = cachedShakeTarget.GetComponent<SmoothShake>();
if (shake == null)
{
shake = cachedShakeTarget.gameObject.AddComponent<SmoothShake>();
}
if (shake.positionShake == null) shake.positionShake = new Shaker();
if (shake.rotationShake == null) shake.rotationShake = new Shaker();
if (shake.shakers == null || shake.shakers.Length != 2)
shake.shakers = new[] { shake.positionShake, shake.rotationShake };
if (shake.sum == null || shake.sum.Length != 2)
shake.sum = new Vector3[2];
}
private void EnsureCameraDriftPivot()
{
if (cachedShakeTarget == null)
return;
if (cachedCameraDriftPivot != null)
return;
Transform currentParent = cachedShakeTarget.parent;
if (currentParent != null && currentParent.name == "__effect_event_camera_drift_pivot")
{
cachedCameraDriftPivot = currentParent;
cameraDriftBaseLocalPosition = cachedCameraDriftPivot.localPosition;
return;
}
GameObject pivotObject = new GameObject("__effect_event_camera_drift_pivot");
Transform pivot = pivotObject.transform;
if (currentParent != null)
{
pivot.SetParent(currentParent, false);
pivot.localPosition = cachedShakeTarget.localPosition;
pivot.localRotation = cachedShakeTarget.localRotation;
pivot.localScale = Vector3.one;
}
else
{
pivot.position = cachedShakeTarget.position;
pivot.rotation = cachedShakeTarget.rotation;
}
cachedShakeTarget.SetParent(pivot, true);
cachedShakeTarget.localRotation = Quaternion.identity;
cachedCameraDriftPivot = pivot;
cameraDriftBaseLocalPosition = cachedCameraDriftPivot.localPosition;
}
private void EnsureCameraSkillPivot()
{
if (cachedShakeTarget == null)
return;
if (cachedCameraSkillPivot != null)
return;
Transform currentParent = cachedShakeTarget.parent;
if (currentParent != null && currentParent.name == "__effect_event_camera_skill_pivot")
{
cachedCameraSkillPivot = currentParent;
cameraSkillBaseLocalPosition = cachedCameraSkillPivot.localPosition;
return;
}
GameObject pivotObject = new GameObject("__effect_event_camera_skill_pivot");
Transform pivot = pivotObject.transform;
if (currentParent != null)
{
pivot.SetParent(currentParent, false);
pivot.localPosition = cachedShakeTarget.localPosition;
pivot.localRotation = cachedShakeTarget.localRotation;
pivot.localScale = Vector3.one;
}
else
{
pivot.position = cachedShakeTarget.position;
pivot.rotation = cachedShakeTarget.rotation;
pivot.localScale = Vector3.one;
}
cachedShakeTarget.SetParent(pivot, true);
cachedShakeTarget.localPosition = Vector3.zero;
cachedShakeTarget.localRotation = Quaternion.identity;
cachedCameraSkillPivot = pivot;
cameraSkillBaseLocalPosition = cachedCameraSkillPivot.localPosition;
}
private void UpdateCameraDrift()
{
if (cachedShakeTarget == null)
{
CacheShakeTarget();
}
if (cachedShakeTarget == null)
return;
EnsureCameraDriftPivot();
if (cachedCameraDriftPivot == null)
return;
if (!enableCameraDrift)
{
ResetCameraDriftIfNeeded();
return;
}
float speed = Mathf.Max(0f, cameraDriftSpeed);
float time = GameplayClock.NowSongTime * speed;
float offsetX = (Mathf.PerlinNoise(cameraDriftSeedX, time) - 0.5f) * 2f * Mathf.Abs(cameraDriftRange.x);
float offsetY = (Mathf.PerlinNoise(cameraDriftSeedY, time) - 0.5f) * 2f * Mathf.Abs(cameraDriftRange.y);
cachedCameraDriftPivot.localPosition = cameraDriftBaseLocalPosition + new Vector3(offsetX, offsetY, 0f);
}
private void ResetCameraDriftIfNeeded()
{
if (cachedCameraDriftPivot == null)
return;
cachedCameraDriftPivot.localPosition = cameraDriftBaseLocalPosition;
}
private void UpdatePlayerSkillCameraOffset()
{
if (cachedShakeTarget == null)
{
CacheShakeTarget();
}
if (cachedShakeTarget == null)
return;
EnsureCameraSkillPivot();
if (cachedCameraSkillPivot == null)
return;
Vector3 targetLocalPosition = cameraSkillBaseLocalPosition;
if (PlayerSkillService.IsSkillEnabled(10))
{
float offset = playerSkillCameraOffsetAmount;
switch (playerSkillCameraOffsetAxis)
{
case CameraOffsetAxis.X:
targetLocalPosition.x += offset;
break;
case CameraOffsetAxis.Y:
targetLocalPosition.y += offset;
break;
case CameraOffsetAxis.Z:
targetLocalPosition.z += offset;
break;
}
}
if (cachedCameraSkillPivot.localPosition != targetLocalPosition)
{
cachedCameraSkillPivot.localPosition = targetLocalPosition;
}
}
public static void RefreshPlayerSkillCameraOffset()
{
effectEventController controller = Instance != null ? Instance : SceneObjectLookupCache.FindAny<effectEventController>();
if (controller == null)
return;
controller.CacheShakeTarget();
controller.UpdatePlayerSkillCameraOffset();
}
public static void TryTriggerMultiNoteShake()
{
effectEventController controller = Instance != null ? Instance : SceneObjectLookupCache.FindAny<effectEventController>();
if (controller == null)
return;
controller.TriggerMultiNoteShakeInternal();
}
public static void TryTriggerTrackCrash(int trackIndex)
{
effectEventController controller = Instance != null ? Instance : SceneObjectLookupCache.FindAny<effectEventController>();
if (controller == null)
return;
controller.TriggerTrackCrashInternal(trackIndex);
}
private void TriggerMultiNoteShakeInternal()
{
if (!enableMultiNoteScreenShake)
return;
if (cachedShakeTarget == null)
{
CacheShakeTarget();
}
if (cachedShakeTarget == null)
return;
float amplitudeValue = Mathf.Max(0f, multiNoteScreenShakeAmplitude);
if (amplitudeValue <= 0f)
return;
SmoothShake shake = cachedShakeTarget.GetComponent<SmoothShake>();
if (shake == null)
{
shake = cachedShakeTarget.gameObject.AddComponent<SmoothShake>();
}
if (shake.positionShake == null) shake.positionShake = new Shaker();
if (shake.rotationShake == null) shake.rotationShake = new Shaker();
shake.positionShake.noiseType = Shaker.NoiseType.SineWave;
shake.positionShake.amplitude = new Vector3(amplitudeValue, amplitudeValue, 0f);
shake.positionShake.frequency = new Vector3(20f, 20f, 0f);
shake.rotationShake.amplitude = Vector3.zero;
shake.rotationShake.frequency = Vector3.zero;
shake.timeSettings.constantShake = false;
shake.timeSettings.fadeInDuration = 0.03f;
shake.timeSettings.holdDuration = 0.04f;
shake.timeSettings.fadeOutDuration = 0.05f;
if (shake.timeSettings.fadeInCurve == null || shake.timeSettings.fadeInCurve.length == 0)
shake.timeSettings.fadeInCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f);
if (shake.timeSettings.fadeOutCurve == null || shake.timeSettings.fadeOutCurve.length == 0)
shake.timeSettings.fadeOutCurve = AnimationCurve.Linear(0f, 1f, 1f, 0f);
shake.shakers = new[] { shake.positionShake, shake.rotationShake };
shake.sum = new Vector3[2];
shake.StartShake();
}
private void TriggerTrackCrashInternal(int trackIndex)
{
CacheTrackCrashController();
if (trackCrashController == null)
return;
trackCrashController.TriggerTrackCrash(trackIndex);
}
}