Files
aibis-dream/Assets/Scripts/MiniGame/Peipei/Eye/EyeSystem.cs
T

492 lines
16 KiB
C#

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;
using AibisDream.Framework;
public class EyeSystem : MonoBehaviour
{
[SerializeField] private List<EyeTarget> targets = new List<EyeTarget>(); // 保存目标列表
public List<EyeTarget> Targets => targets; // 提供目标列表的公共访问
private EyeTarget currentTarget; // 当前选中的目标
public EyeTarget CurrentTarget => currentTarget; // 提供当前目标的公共访问
public RawImage eyeImage;
public Image memoryRender;
public Button backToFaceButton;
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<ICinemachineCamera>();
var virtualCamDeep = transform.Find("Eye DeepCamera").GetComponent<ICinemachineCamera>();
CameraKit.Instance.RegisterCamera(CameraEnum.Eye, virtualCam);
CameraKit.Instance.RegisterCamera(CameraEnum.EyeDeep, virtualCamDeep);
GameLoopManager.FixDataContainer.Register(_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()
{
eyeStateEffect?.CleanupEffect(CurrentTarget);
mouseFollowAndZoom.SetIsActive(false);
currentTarget = null;
CloseEyeView();
// 离开视图时的逻辑
Debug.Log("EyeView exited.");
}
private void Start()
{
SetEyeColorState(_eyeData.currentState);
if (targets.Count > 0)
{
//SetInitialTargetState(targets[1]);
}
mouseFollowAndZoom = FindObjectOfType<MouseFollowAndZoom>();
//eyeView.SetActive(false);
//LostColor();
}
public void SetInitialTargetState(EyeTarget target)
{
currentTarget = target;
eyeStateEffect?.InitializeEffect(target, cameraManager);
}
public EyeTarget FindEyeTargetByName(string name)
{
return Targets.FirstOrDefault(target => target.gameObject.name == name);
}
public void SetTarget(EyeTarget newTarget)
{
// if (newTarget != currentTarget)
// {
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;
}
// if (currentTarget == target)
// {
// DialogController.Instance.SetVariable("$currentEyeTarget",target.name);
// yield break;
// }
DialogController.Instance.SetVariable("$currentEyeTarget", target.name);
StartCoroutine(EyeEffectFadeOut());
float duration = eyeStateEffect.TransitionDuration;
if (target.targetTransform != null)
{
cameraManager.MoveCameraTo(target.targetTransform, 1f);
}
else
{
cameraManager.MoveCameraTo(target.transform, 1f);
}
if(currentTarget!=null)
{
currentTarget.BlurIn(eyeStateEffect.TransitionDuration, false);
}
//yield return new WaitForSeconds(eyeStateEffect.TransitionDuration);
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");
}
//mouseFollowAndZoom.SetIsActive(true);
}
[YarnCommand("Set_MouseMovementLockState")]
public void SetMouseMovementLockState(bool isActive)
{
mouseFollowAndZoom.SetIsLock(isActive);
}
[YarnCommand("EyeEffect_FadeIn")]
public IEnumerator EyeEffectFadeIn()
{
if (currentTarget != null)
{
// AudioManager.RandomPlayInteraction("colorimagine");
eyeStateEffect?.ApplyFocusedEffect(currentTarget);
}
yield return new WaitForSeconds(eyeStateEffect.TransitionDuration);
}
[YarnCommand("EyeEffect_FadeOut")]
public IEnumerator EyeEffectFadeOut()
{
if (currentTarget != null)
{
// AudioManager.RandomPlayInteraction("colorimagine");
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)
{
EyeData.EyeColorState eyeState;
// Try to parse the string as an EyeColorState
if (!Enum.TryParse(state, true, out 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();
//isFirstSetTargetAfterStateChange = true;
break;
case EyeData.EyeColorState.CannotImagineColor:
eyeStateEffect = new CannotImagineColorEffect();
//isFirstSetTargetAfterStateChange = true;
break;
case EyeData.EyeColorState.EyeDisorder:
eyeStateEffect = new EyeDisorderEffect();
//isFirstSetTargetAfterStateChange = true;
break;
case EyeData.EyeColorState.CanSeeColor:
eyeStateEffect = new CanSeeColorEffect();
//isFirstSetTargetAfterStateChange = false;
break;
case EyeData.EyeColorState.HaveChip:
eyeStateEffect = new HaveChip();
//isFirstSetTargetAfterStateChange = false;
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");
// _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<Sprite>("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 void LostColor()
{
// 对目标列表中的每个目标执行 ColorBack 方法
foreach (EyeTarget target in targets)
{
target.ColorLost();
}
}
}
public class EyeData : IData
{
public enum EyeColorState
{
CanImagineColor,
CannotImagineColor,
EyeDisorder,
CanSeeColor,
HaveChip
}
public EyeColorState currentState = EyeColorState.CannotImagineColor;
public event Action<EyeData> LoadEvent;
public void Load()
{
LoadEvent?.Invoke(this);
}
}