483 lines
14 KiB
C#
483 lines
14 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 AibisDream.Framework;
|
|
//using AibisDream.Kit;
|
|
//using Framework.Core;
|
|
using AibisDream;
|
|
|
|
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 enum EyeState
|
|
{
|
|
CanImagineColor,
|
|
CannotImagineColor,
|
|
EyeDisorder,
|
|
CanSeeColor,
|
|
HaveChip
|
|
}
|
|
public ViewCameraManager cameraManager;
|
|
|
|
private IEyeStateEffect eyeStateEffect;
|
|
|
|
private EyeState currentState=EyeState.CannotImagineColor;
|
|
public EyeState CurrentState
|
|
{
|
|
get { return currentState; }
|
|
set
|
|
{
|
|
if (currentState != value)
|
|
{
|
|
SetEyeState(currentState);
|
|
// StartCoroutine(SetEyeStateCoroutine(currentState));
|
|
currentState = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private Tween hsvShiftTween;
|
|
private MouseFollowAndZoom mouseFollowAndZoom;
|
|
|
|
|
|
|
|
public void Initialize()
|
|
{
|
|
// 初始化逻辑
|
|
Debug.Log("EyeView initialized.");
|
|
}
|
|
private void Awake()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
|
|
public void Init()
|
|
{
|
|
FixSystemCenter.SystemDic.Register(this);
|
|
}
|
|
|
|
public void OnEnter()
|
|
{
|
|
//SetInitialTargetState(targets[1]);
|
|
mouseFollowAndZoom.SetIsActive(true);
|
|
mouseFollowAndZoom.SetIsLock(false);
|
|
// 进入视图时的逻辑
|
|
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);
|
|
// 离开视图时的逻辑
|
|
Debug.Log("EyeView exited.");
|
|
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
SetEyeState(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)
|
|
{
|
|
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);
|
|
}
|
|
currentTarget.BlurIn(eyeStateEffect.TransitionDuration,false);
|
|
|
|
//yield return new WaitForSeconds(eyeStateEffect.TransitionDuration);
|
|
|
|
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_EyeState")]
|
|
public void SetEyeStateForYarn(string state)
|
|
{
|
|
EyeState eyeState;
|
|
|
|
// Try to parse the string as an EyeState
|
|
if (!Enum.TryParse(state, true, out eyeState))
|
|
{
|
|
throw new ArgumentException("Invalid eye state: " + state, nameof(state));
|
|
}
|
|
|
|
// Start the coroutine for setting the eye state
|
|
SetEyeState(eyeState);
|
|
}
|
|
|
|
private void SetEyeState(EyeState state)
|
|
{
|
|
// 保存旧的状态
|
|
//oldEyeStateEffect = eyeStateEffect;
|
|
switch (state)
|
|
{
|
|
case EyeState.CanImagineColor:
|
|
eyeStateEffect = new CanImagineColorEffect();
|
|
//isFirstSetTargetAfterStateChange = true;
|
|
break;
|
|
case EyeState.CannotImagineColor:
|
|
eyeStateEffect = new CannotImagineColorEffect();
|
|
//isFirstSetTargetAfterStateChange = true;
|
|
break;
|
|
case EyeState.EyeDisorder:
|
|
eyeStateEffect = new EyeDisorderEffect();
|
|
//isFirstSetTargetAfterStateChange = true;
|
|
break;
|
|
case EyeState.CanSeeColor:
|
|
eyeStateEffect = new CanSeeColorEffect();
|
|
//isFirstSetTargetAfterStateChange = false;
|
|
break;
|
|
case EyeState.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()
|
|
{
|
|
SetEyeState(EyeState.CanImagineColor);
|
|
// 对目标列表中的每个目标执行 ColorBack 方法
|
|
foreach (EyeTarget target in targets)
|
|
{
|
|
target.ColorBack();
|
|
}
|
|
|
|
// 切换到 CanImagineColorEffect 状态
|
|
|
|
}
|
|
public void LostColor()
|
|
{
|
|
// 对目标列表中的每个目标执行 ColorBack 方法
|
|
foreach (EyeTarget target in targets)
|
|
{
|
|
target.ColorLost();
|
|
}
|
|
}
|
|
|
|
}
|
|
|