using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; using Yarn.Unity; using AibisDream; using AibisDream.FixSystem; using AibisDream.Framework; using Cinemachine; using UnityEngine.Rendering; using AibisDream.Kit; using UnityEngine.EventSystems; public class MemoryProcess : MonoBehaviour { public BubbleSlotGroup bubbleSlotGroup; public GameObject memoryView; public GameObject projector; public SpriteRenderer memoryFinishedspRender; // 用于显示记忆处理结束的表现 public SpriteRenderer memoryFinishedImageNoColor; // 用于显示记忆处理结束的表现 [SerializeField] private Volume MainEffect; [SerializeField] private Volume MemoryClarityVloume; [SerializeField] private Volume Memoryfrequencyloume; [SerializeField] private Volume MemoryProcessVloume; public Slider frequencySlider; // 频率调节滑动条 public Slider claritySlider; // 频率调节滑动条 public CanvasGroup playBackground; public float targetFrequency = 1.25f; // 目标频率 public float targetClarity = 5.7f; // 目标频率 private GameObject memoryGroup; private float lockThreshold = 0.06f; // 锁定阈值 private bool isProcessing = false; // 新增变量来追踪是否正在处理记忆 private FMOD.Studio.EventInstance faderSoundInstance; // 添加音效实例变量 private bool isPlayingFaderSound = false; // 追踪音效是否正在播放 private float lastFrequencyValue; // 记录上一帧的频率值 private float lastClarityValue; // 记录上一帧的清晰度值 private bool isColorful = false; // private bool isFrequencyFound = false; // 追踪是否找到目标频率 private bool isClarityFound = false; // 追踪是否找到目标清晰度 private Material memoryMaterial; // 噪波材质 private PunchTape PunchTape; private MemoryClueSlot clueSlot; public Material fadeMaterial; private Dictionary processedPunchTapes = new Dictionary(); public void OpenMemoryView() { memoryView.gameObject.SetActive(true); memoryGroup.SetActive(true); } public IEnumerator DropMemoryProjector() { DG.Tweening.Sequence zoomInSequence = DOTween.Sequence(); zoomInSequence.Append(projector.transform.DOLocalMoveY(-5, 2f).SetEase(Ease.OutElastic, 0.5f)); yield return zoomInSequence.WaitForCompletion(); } public void PullMemoryProjector() { DG.Tweening.Sequence zoomOutSequence = DOTween.Sequence(); zoomOutSequence.Append(projector.transform.DOLocalMoveY(0, 2f).SetEase(Ease.OutElastic, 0.5f)); //yield return zoomOutSequence.WaitForCompletion(); } public void CloseMemoryView() { memoryView.gameObject.SetActive(false); memoryGroup.SetActive(false); } public void OnEnter() { OpenMemoryView(); clueSlot = FindObjectOfType(); FavoritesManager.Instance.OpenFavorites(); playBackground.gameObject.SetActive(false); playBackground.alpha = 0; } public void OnShow() { Debug.Log("memoryView showed."); clueSlot = FindObjectOfType(); FavoritesManager.Instance.OpenFavorites(); playBackground.gameObject.SetActive(false); playBackground.alpha = 0; } public void OnExit() { // 停止拉条音频 if (isPlayingFaderSound) { AudioManager.Instance.StopSfx("event:/ActionFB/mem_fader"); isPlayingFaderSound = false; } FavoritesManager.Instance.CloseFavorites(); CloseMemoryView(); // 离开视图时的逻辑 Debug.Log("MemoryView exited."); } private void Awake() { InitSystem(); } private void InitSystem() { FixSystemCenter.SystemDic.Register(this); memoryGroup = transform.Find("Memory Group").gameObject; memoryGroup.SetActive(false); var virtualCam = transform.Find("Memory Camera").GetComponent(); CameraKit.Instance.RegisterCamera(CameraEnum.Memory, virtualCam); } private void Start() { Init(); } float GetRandomNumber() { // 随机决定选择哪个区间 if (UnityEngine.Random.value < 0.5f) // 50% 概率选择第一个区间 { return UnityEngine.Random.Range(0.5f, 2f); } else // 50% 概率选择第二个区间 { return UnityEngine.Random.Range(4f, 5.5f); } } void OnFrequencyChanged(float value) { float distance = Mathf.Abs(value - targetFrequency); float maxDistance = Mathf.Max( Mathf.Abs(frequencySlider.maxValue - targetFrequency), Mathf.Abs(frequencySlider.minValue - targetFrequency) ); float t = Mathf.Clamp01(distance / maxDistance); UpdateFrequencyShaderParameters(t); CheckIfFound(t, ref isFrequencyFound); // 控制音效 - 使用更平滑的速度计算 float currentSpeed = Mathf.Abs(value - lastFrequencyValue) / Time.deltaTime; lastFrequencyValue = value; // UpdateFaderSound(currentSpeed); } void OnClarityChanged(float value) { float distance = Mathf.Abs(value - targetClarity); float maxDistance = Mathf.Max( Mathf.Abs(claritySlider.maxValue - targetClarity), Mathf.Abs(claritySlider.minValue - targetClarity) ); float t = Mathf.Clamp01(distance / maxDistance); UpdateClarityShaderParameters(t); CheckIfFound(t, ref isClarityFound); // 控制音效 - 使用更平滑的速度计算 float currentSpeed = Mathf.Abs(value - lastClarityValue) / Time.deltaTime; lastClarityValue = value; // UpdateFaderSound(currentSpeed); } void OnSearchComplete() { Debug.Log("Memory search completed."); frequencySlider.interactable = false; claritySlider.interactable = false; // 停止拉条音频 if (isPlayingFaderSound) { AudioManager.Instance.StopSfx("event:/ActionFB/mem_fader"); isPlayingFaderSound = false; } AudioManager.Instance.SetSfxParam("event:/Amb/amb_mem_tuning", "is_mem_tuning", 0); StartCoroutine(PlayMemory()); } void CheckIfFound(float distance, ref bool isFound) { if (distance < lockThreshold) { isFound = true; // 检查是否两个条件都满足 if (isFrequencyFound && isClarityFound) { OnSearchComplete(); // 一旦条件满足,调用完成处理 } } else { isFound = false; } } void UpdateFrequencyShaderParameters(float distance) { Memoryfrequencyloume.weight = Mathf.Lerp(0, 1, distance); } void UpdateClarityShaderParameters(float t) { MemoryClarityVloume.weight = Mathf.Lerp(0, 1, t); } public void TweenWeight(Volume postProcessingVolume, float targetWeight, float duration) { // 动态调整权重 DOTween.To(() => postProcessingVolume.weight, x => postProcessingVolume.weight = x, targetWeight, duration); } public void Init() { isFrequencyFound = false; isClarityFound = false; isProcessing = false; // 停止拉条音频 if (isPlayingFaderSound) { AudioManager.Instance.StopSfx("event:/ActionFB/mem_fader"); isPlayingFaderSound = false; } if (frequencySlider != null) { frequencySlider.onValueChanged.AddListener(OnFrequencyChanged); frequencySlider.gameObject.SetActive(false); frequencySlider.value = 3; lastFrequencyValue = frequencySlider.value; frequencySlider.interactable = true; // 添加EventTrigger监听 var trigger = frequencySlider.gameObject.GetComponent() ?? frequencySlider.gameObject.AddComponent(); var entryDown = new EventTrigger.Entry { eventID = EventTriggerType.PointerDown }; entryDown.callback.AddListener((data) => OnFaderPointerDown()); trigger.triggers.Add(entryDown); var entryUp = new EventTrigger.Entry { eventID = EventTriggerType.PointerUp }; entryUp.callback.AddListener((data) => OnFaderPointerUp()); trigger.triggers.Add(entryUp); } if (claritySlider != null) { claritySlider.onValueChanged.AddListener(OnClarityChanged); claritySlider.gameObject.SetActive(false); claritySlider.value = 3; lastClarityValue = claritySlider.value; claritySlider.interactable = true; // 添加EventTrigger监听 var trigger = claritySlider.gameObject.GetComponent() ?? claritySlider.gameObject.AddComponent(); var entryDown = new EventTrigger.Entry { eventID = EventTriggerType.PointerDown }; entryDown.callback.AddListener((data) => OnFaderPointerDown()); trigger.triggers.Add(entryDown); var entryUp = new EventTrigger.Entry { eventID = EventTriggerType.PointerUp }; entryUp.callback.AddListener((data) => OnFaderPointerUp()); trigger.triggers.Add(entryUp); } fadeMaterial.SetFloat("_DirectionalDistortionFade", -15f); memoryFinishedspRender.color = Color.black; MemoryProcessVloume.weight = 0; MemoryClarityVloume.weight = 0; Memoryfrequencyloume.weight = 0; PunchTape = null; playBackground.gameObject.SetActive(false); playBackground.alpha = 0; } [YarnCommand("MemoryFinished")] public IEnumerator MemoryFinished() { // AudioManager.PauseMemoryAudio(); // Fade out alpha from 1 to 0 yield return playBackground.DOFade(0f, 1f).WaitForCompletion(); // Fade to fully transparent over 1 second // Deactivate playBackground after fade out playBackground.gameObject.SetActive(false); FavoritesManager.Instance.OpenFavorites(); // Initialize and release slot Init(); clueSlot.punchTape.used = true; clueSlot.ReleaseSlot(); } [YarnCommand("ColorFadeOut")] public IEnumerator ColorFadeOut() { fadeMaterial.SetFloat("_DirectionalDistortionFade", -15f); // AudioManager.PauseMemoryAudio(); Tween tween = fadeMaterial.DOFloat(0, "_DirectionalDistortionFade", 3); yield return tween.WaitForCompletion(); } [YarnCommand("PlayMemory")] public IEnumerator PlayMemory(bool useYarn = false, string memName = "") { memoryFinishedspRender.color = Color.white; if (useYarn) { fadeMaterial.SetFloat("_DirectionalDistortionFade", -15); FavoritesManager.Instance.CloseFavorites(); Sprite memSprite = Resources.Load("Art/Memory/" + memName); memoryFinishedspRender.sprite = memSprite; memoryFinishedImageNoColor.sprite = memSprite; if (memSprite == null) { Debug.LogError("Memory not found: " + memName); } // AudioManager.PlayMemoryAudio("mem_" + memName); playBackground.gameObject.SetActive(true); //FavoritesManager.Instance.CloseFavorites(); playBackground.alpha = 0; AudioManager.Instance.PlaySfx("event:/ActionFB/mem_play"); yield return playBackground.DOFade(1f, 1f).WaitForCompletion(); // Fade to fully opaque over 1 second MemoryClarityVloume.weight = 0; Memoryfrequencyloume.weight = 0; } else { FavoritesManager.Instance.CloseFavorites(); // Activate playBackground and fade in alpha from 0 to 1 // AudioManager.PlayMemoryAudio("mem_" + clueSlot.punchTape.MemoryIndex); playBackground.gameObject.SetActive(true); //FavoritesManager.Instance.CloseFavorites(); playBackground.alpha = 0; AudioManager.Instance.PlaySfx("event:/ActionFB/mem_play"); yield return playBackground.DOFade(1f, 1f).WaitForCompletion(); // Fade to fully opaque over 1 second // Set material properties MemoryClarityVloume.weight = 0; Memoryfrequencyloume.weight = 0; DialogController.Instance.StartDialogNode(clueSlot.punchTape.YarnNodeName); } } [YarnCommand("search_memory")] public IEnumerator SearchMemory(PunchTape punchTape, bool isSkipDialogue = false) { // 停止之前的拉条音频 if (isPlayingFaderSound) { AudioManager.Instance.StopSfx("event:/ActionFB/mem_fader"); isPlayingFaderSound = false; } targetClarity = GetRandomNumber(); targetFrequency = GetRandomNumber(); FavoritesManager.Instance.CloseFavorites(); //FavoritesManager.Instance.CloseFavorites(); if (punchTape == null) { Debug.Log("no punchTape"); yield break; } PunchTape = punchTape; // AudioManager.PauseMemoryAudio(); if (isProcessing) { Debug.LogWarning("Already processing a memory. Please wait until the process is finished."); yield break; } Sprite memorySprite = Resources.Load("Art/Memory/" + PunchTape.MemoryIndex); memoryFinishedspRender.sprite = memorySprite; memoryFinishedImageNoColor.sprite = memorySprite; if (memorySprite == null) { Debug.LogError("Memory not found: " + PunchTape.MemoryIndex); } MemoryProcessVloume.weight = 1; AudioManager.Instance.PlaySfx("event:/Scriptal/mem_load"); yield return new WaitForSeconds(1f); AudioManager.Instance.SetSfxParam("event:/Amb/amb_mem_tuning", "is_mem_tuning", 1); memoryFinishedspRender.color = Color.white; OnFrequencyChanged(frequencySlider.value); OnClarityChanged(claritySlider.value); MemoryProcessVloume.weight = 0; isProcessing = true; // 开始处理,设置为true frequencySlider.gameObject.SetActive(true); claritySlider.gameObject.SetActive(true); DG.Tweening.Sequence memorySequence = DOTween.Sequence(); yield return memorySequence.WaitForCompletion(); } public bool IsProcessing() { return isProcessing; } private void OnFaderPointerDown() { // if (!isPlayingFaderSound) // { // AudioManager.Instance.PlaySfx("event:/ActionFB/mem_fader"); // isPlayingFaderSound = true; // } } private void OnFaderPointerUp() { // if (isPlayingFaderSound) // { // AudioManager.Instance.StopSfx("event:/ActionFB/mem_fader"); // isPlayingFaderSound = false; // } } // private void UpdateFaderSound(float speed) // { // // 速度归一化,最大速度可根据实际情况调整 // float normalizedSpeed = Mathf.Clamp01(speed / 10f); // AudioManager.Instance.SetSfxParam("event:/ActionFB/mem_fader", "mem_fader_speed", normalizedSpeed); // } }