using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using Yarn.Unity; using System.Linq; using UnityEngine.UI; using AibisDream.FixSystem; using Cinemachine; using AibisDream.Framework; using AibisDream.Kit; using Sequence = DG.Tweening.Sequence; namespace AibisDream { public class EyeSystem : MonoBehaviour { [SerializeField] private List targets = new(); // 保存目标列表 public List Targets => targets; // 提供目标列表的公共访问 private EyeTarget currentTarget; // 当前选中的目标 public EyeTarget CurrentTarget => currentTarget; // 提供当前目标的公共访问 public RawImage eyeImage; public Image memoryRender; public GameObject eyeView; public ViewCameraManager cameraManager; private IEyeStateEffect eyeStateEffect; private EyeData _eyeData = new(); private Tween hsvShiftTween; private MouseFollowAndZoom mouseFollowAndZoom; private void Awake() { Init(); } public void Init() { FixSystemCenter.SystemDic.Register(this); var virtualCam = transform.Find("Eye Camera").GetComponent(); var virtualCamDeep = transform.Find("Eye DeepCamera").GetComponent(); CameraKit.Instance.RegisterCamera(CameraEnum.Eye, virtualCam); CameraKit.Instance.RegisterCamera(CameraEnum.EyeDeep, virtualCamDeep); StorageSystem.Instance.RegisterData(_eyeData); // 添加加载逻辑 _eyeData.LoadEvent += LoadData; } private void LoadData(EyeData eyedata) { SetEyeColorState(eyedata.currentState); } public void OnEnter() { mouseFollowAndZoom.SetIsActive(true); mouseFollowAndZoom.SetIsLock(false); OpenEyeView(); // 进入视图时的逻辑 Debug.Log("EyeView entered."); } public void OpenEyeView() { eyeView.SetActive(true); } public void CloseEyeView() { eyeView.SetActive(false); } public void OnShow() { // 离开视图时的逻辑 Debug.Log("EyeView showed."); } public void OnExit() { if (currentTarget != null) { eyeStateEffect?.CleanupEffect(CurrentTarget); } mouseFollowAndZoom.SetIsActive(false); currentTarget = null; CloseEyeView(); // 离开视图时的逻辑 Debug.Log("EyeView exited."); } private void Start() { SetEyeColorState(_eyeData.currentState); mouseFollowAndZoom = FindObjectOfType(); } public EyeTarget FindEyeTargetByName(string name) { return Targets.FirstOrDefault(target => target.gameObject.name == name); } public void SetTarget(EyeTarget newTarget) { if (newTarget == null) { Debug.LogError("Target is null in SetTarget"); return; } StartCoroutine(SetTargetCoroutine(newTarget.gameObject.name)); } [YarnCommand("set_Eyetarget")] public IEnumerator SetTargetCoroutine(string targetName, bool startDialogue = true) { mouseFollowAndZoom.SetIsLock(true); EyeTarget target = FindEyeTargetByName(targetName); if (target == null) { Debug.LogError("Invalid EyeTarget name: " + targetName); yield break; } StorageSystem.Instance.SetValue("$currentEyeTarget", target.name); StartCoroutine(EyeEffectFadeOut()); cameraManager.MoveCameraTo(target.targetTransform ? target.targetTransform : target.transform, 1f); if (currentTarget != null) { currentTarget.BlurIn(eyeStateEffect.TransitionDuration, false); } if (currentTarget == target) { DialogController.Instance.StartDialogNode("重复看同一个目标"); currentTarget = target; mouseFollowAndZoom.SetIndicatorTarget(currentTarget); currentTarget.BlurOut(eyeStateEffect.TransitionDuration, false); yield return new WaitForSeconds(eyeStateEffect.TransitionDuration); yield break; } currentTarget = target; mouseFollowAndZoom.SetIndicatorTarget(currentTarget); currentTarget.BlurOut(eyeStateEffect.TransitionDuration, false); yield return new WaitForSeconds(eyeStateEffect.TransitionDuration); if (startDialogue) { DialogController.Instance.StartDialogNode("IntoEyeView"); } } [YarnCommand("Set_MouseMovementLockState")] public void SetMouseMovementLockState(bool isActive) { mouseFollowAndZoom.SetIsLock(isActive); } [YarnCommand("EyeEffect_FadeIn")] public IEnumerator EyeEffectFadeIn() { if (currentTarget != null) { // AudioManager.RandomPlayInteraction("colorimagine"); AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine"); eyeStateEffect?.ApplyFocusedEffect(currentTarget); } yield return new WaitForSeconds(eyeStateEffect.TransitionDuration); } [YarnCommand("EyeEffect_FadeOut")] public IEnumerator EyeEffectFadeOut() { if (currentTarget != null) { // AudioManager.RandomPlayInteraction("colorimagine"); AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine"); eyeStateEffect?.ApplyUnfocusedEffect(currentTarget); } yield return new WaitForSeconds(eyeStateEffect.TransitionDuration); } [YarnCommand("EyeEffect_Init")] public void EyeEffectInit() { foreach (EyeTarget target in targets) { target.Init(); } if (currentTarget != null) { eyeStateEffect?.InitializeEffect(currentTarget, cameraManager); } } [YarnCommand("EyeEffect_Clean")] public void EyeEffectClean() { if (currentTarget != null) { eyeStateEffect?.CleanupEffect(currentTarget); } } [YarnCommand("set_EyeColorState")] public void SetEyeColorStateForYarn(string state) { // Try to parse the string as an EyeColorState if (!Enum.TryParse(state, true, out EyeData.EyeColorState eyeState)) { throw new ArgumentException("Invalid eye state: " + state, nameof(state)); } // Start the coroutine for setting the eye state SetEyeColorState(eyeState); } private void SetEyeColorState(EyeData.EyeColorState state) { _eyeData.currentState = state; switch (state) { case EyeData.EyeColorState.CanImagineColor: eyeStateEffect = new CanImagineColorEffect(); break; case EyeData.EyeColorState.CannotImagineColor: eyeStateEffect = new CannotImagineColorEffect(); break; case EyeData.EyeColorState.EyeDisorder: eyeStateEffect = new EyeDisorderEffect(); break; case EyeData.EyeColorState.CanSeeColor: eyeStateEffect = new CanSeeColorEffect(); break; case EyeData.EyeColorState.HaveChip: eyeStateEffect = new HaveChip(); break; default: throw new ArgumentException("Unknown eye state: " + state.ToString(), nameof(state)); } } [YarnCommand("Set_Saturation")] public IEnumerator Set_Saturation(float targetSaturation, float duration) { // 确保 targetSaturation 在 0 到 1 之间 targetSaturation = Mathf.Clamp01(targetSaturation); Material material = eyeImage.material; Sequence saturationSequence = DOTween.Sequence(); // 使用映射函数将目标饱和度转换为 ColorAdjustments 的范围 float mappedSaturation = MapSaturation(targetSaturation); // 同时启动材质的饱和度变化和 ColorAdjustments 的饱和度变化 saturationSequence.Join(material.DOFloat(targetSaturation, "_HsvSaturation", duration)); // 获取 Tween 对象并添加到序列中 Tween saturationTween = ScreenEffectManager.Instance.TweenSaturation(mappedSaturation, duration); if (saturationTween != null) { saturationSequence.Join(saturationTween); } // 启动 Sequence 并等待完成 yield return saturationSequence.WaitForCompletion(); } private float MapSaturation(float input) { return Mathf.Lerp(-100, 0, input); } private Sequence glitchin; [YarnCommand("EyeGlitch_in")] public IEnumerator EyeGlitch_in() { glitchin = DOTween.Sequence(); Material material = eyeImage.material; if (eyeImage == null) { Debug.LogError("No eyeImage"); yield break; } // AudioManager.RandomPlayInteraction("colorcorrect_in"); // AudioManager.PlayLoopAudio("colorcorrect_loop"); //AudioManager.Instance.PlaySfx("event:/ActionFB/visualturn"); // _HsvShift 从 0 ~ 360 来回变化 hsvShiftTween = DOTween .To(() => material.GetFloat("_HsvShift"), x => material.SetFloat("_HsvShift", x), 360, 1f) .SetLoops(-1, LoopType.Yoyo); glitchin.Append(hsvShiftTween); // _GlitchAmount 1 秒内从 0 ~ 8 glitchin.Insert(0, DOTween.To(() => material.GetFloat("_GlitchAmount"), x => material.SetFloat("_GlitchAmount", x), 8, 1f)); // _WarpStrength 1 秒内从 0 ~ 0.015 glitchin.Insert(0, DOTween.To(() => material.GetFloat("_WarpStrength"), x => material.SetFloat("_WarpStrength", x), 0.015f, 1f)); yield return new WaitForSeconds(1f); } [YarnCommand("EyeGlitch_out")] public void EyeGlitch_out(float duration) { Material material = eyeImage.material; if (eyeImage == null) { Debug.LogError("No eyeImage"); return; } if (glitchin != null && glitchin.IsActive()) { glitchin.Kill(); } material.DOFloat(0, "_WarpStrength", duration); material.DOFloat(0, "_GlitchAmount", duration); material.DOFloat(0, "_HsvShift", duration); // 确保之前的动画被停止 } [YarnCommand("set_EyeColor")] public IEnumerator SetEyeColor(string color, string memoryName = null) { Material material = eyeImage.material; Material memoryMaterial = memoryRender.material; memoryRender.sprite = null; memoryMaterial.SetFloat("_FullDistortionFade", 0f); memoryMaterial.SetFloat("_SqueezePower", 18f); if (eyeImage == null) { Debug.LogError("No eyeImage"); yield break; } if (memoryName != null) { Sprite memorySprite = Resources.Load("Art/Memory/" + memoryName); if (memorySprite == null) { Debug.LogWarning("Memory not found: " + memoryName); yield break; } memoryRender.sprite = memorySprite; // 使 memoryRender 可见 memoryRender.gameObject.SetActive(true); // 创建一个新的 DOTween 序列 Sequence memorySequence = DOTween.Sequence(); memorySequence.Append(memoryMaterial.DOFloat(0.85f, "_FullDistortionFade", 1.5f)); memorySequence.AppendInterval(1.5f); memorySequence.Append(memoryMaterial.DOFloat(0f, "_SqueezePower", 2f)); memorySequence.Insert(4.5f, memoryMaterial.DOFloat(0f, "_FullDistortionFade", 0.5f).OnComplete(() => { memoryRender.gameObject.SetActive(false); // AudioManager.RandomPlayInteraction("water_drip"); })); // 等待序列完成 yield return memorySequence.WaitForCompletion(); } Sequence sequence = DOTween.Sequence(); // 添加一个 tween 来改变 _RoundWaveStrength 的值 sequence.Append(material.DOFloat(1, "_RoundWaveStrength", 2)).OnComplete(() => { EyeGlitch_out(0.5f); }); // 根据颜色改变 _ColorChangeTolerance 的值 switch (color.ToLower()) { case "blue": sequence.Join(material.DOFloat(0, "_ColorChangeTolerance", 2)); sequence.Join(material.DOFloat(1, "_ColorChangeTolerance3", 2)); sequence.Join(material.DOFloat(1, "_ColorChangeTolerance2", 2)); break; case "red": sequence.Join(material.DOFloat(0, "_ColorChangeTolerance3", 2)); sequence.Join(material.DOFloat(1, "_ColorChangeTolerance", 2)); sequence.Join(material.DOFloat(1, "_ColorChangeTolerance2", 2)); break; case "green": sequence.Join(material.DOFloat(0, "_ColorChangeTolerance2", 2)); sequence.Join(material.DOFloat(1, "_ColorChangeTolerance", 2)); sequence.Join(material.DOFloat(1, "_ColorChangeTolerance3", 2)); break; case "All": sequence.Join(material.DOFloat(1, "_ColorChangeTolerance2", 2)); sequence.Join(material.DOFloat(1, "_ColorChangeTolerance", 2)); sequence.Join(material.DOFloat(1, "_ColorChangeTolerance3", 2)); break; default: Debug.LogWarning("Unknown color: " + color); break; } // 添加一个 tween 来将 _RoundWaveStrength 的值回复为 0 sequence.Append(material.DOFloat(0, "_RoundWaveStrength", 0.5f)); // 开始这个序列 sequence.Play(); // 等待序列完成 yield return sequence.WaitForCompletion(); } [YarnCommand("EyeGetColor")] public void GetColor() { SetEyeColorState(EyeData.EyeColorState.CanImagineColor); // 对目标列表中的每个目标执行 ColorBack 方法 foreach (EyeTarget target in targets) { target.ColorBack(); } // 切换到 CanImagineColorEffect 状态 } } public class EyeData : IData { public enum EyeColorState { CanImagineColor, CannotImagineColor, EyeDisorder, CanSeeColor, HaveChip } public EyeColorState currentState = EyeColorState.CannotImagineColor; public event Action LoadEvent; public IEnumerator Load() { LoadEvent?.Invoke(this); yield break; } } }