refactor(peipei-eye): 重构 Eye 上色为 unified 驱动并集中调参
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f92d49bad6ceaa4983976ea6bb47c46
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
[CustomEditor(typeof(EyeSystem))]
|
||||
public class EyeSystemEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
DrawPropertiesExcluding(serializedObject, "m_Script", "visualSettings", "replayFocusedEffectOnSettingsChange");
|
||||
|
||||
SerializedProperty visualSettings = serializedObject.FindProperty("visualSettings");
|
||||
SerializedProperty replayOnChange = serializedObject.FindProperty("replayFocusedEffectOnSettingsChange");
|
||||
|
||||
if (visualSettings != null)
|
||||
{
|
||||
EditorGUILayout.Space(6f);
|
||||
EditorGUILayout.LabelField("Visual Tuning", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(visualSettings, includeChildren: true);
|
||||
bool visualChanged = EditorGUI.EndChangeCheck();
|
||||
|
||||
EditorGUILayout.Space(4f);
|
||||
EditorGUILayout.PropertyField(replayOnChange);
|
||||
|
||||
EditorGUILayout.HelpBox(
|
||||
"Blur / Reveal 扫过 / Wrong Color / HSV:改完即写入材质。\n" +
|
||||
"时长 / colorReveal 范围:Play 下需勾选「自动重播」或点「重播当前目标效果」。\n" +
|
||||
"Edit 模式:改参数后会自动把所有目标重置为 idle(灰+糊)预览。",
|
||||
MessageType.Info);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("立即应用(Idle 预览)"))
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
GetEyeSystem().ApplyVisualSettingsNow(previewIdleState: true);
|
||||
}
|
||||
|
||||
if (GUILayout.Button("重播当前目标效果"))
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
GetEyeSystem().ApplyVisualSettingsNow(replayFocusedEffect: true);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (visualChanged)
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
var system = GetEyeSystem();
|
||||
system.ApplyVisualSettingsNow(
|
||||
previewIdleState: !Application.isPlaying,
|
||||
replayFocusedEffect: Application.isPlaying && replayOnChange.boolValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox(
|
||||
"visualSettings 未找到。请确认 EyeSystem.cs 已编译通过。",
|
||||
MessageType.Warning);
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private EyeSystem GetEyeSystem()
|
||||
{
|
||||
return (EyeSystem)target;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 193d982b27c7dd34cb2aa48c07b1df09
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
@@ -19,20 +19,82 @@ namespace AibisDream
|
||||
{
|
||||
private const string MemorySpritePath = "Sprite/Memory/{0}.png";
|
||||
|
||||
[SerializeField] private List<EyeTarget> targets = new(); // 保存目标列表
|
||||
public List<EyeTarget> Targets => targets; // 提供目标列表的公共访问
|
||||
private EyeTarget currentTarget; // 当前选中的目标
|
||||
public EyeTarget CurrentTarget => currentTarget; // 提供当前目标的公共访问
|
||||
public RawImage eyeImage;
|
||||
[SerializeField] private List<EyeTarget> targets = new();
|
||||
public List<EyeTarget> Targets => targets;
|
||||
|
||||
private EyeTarget currentTarget;
|
||||
public EyeTarget CurrentTarget => currentTarget;
|
||||
|
||||
[Header("Memory Overlay (UI)")]
|
||||
public Image memoryRender;
|
||||
public GameObject eyeView;
|
||||
public ViewCameraManager cameraManager;
|
||||
|
||||
[Header("Focus Pan Bounds")]
|
||||
[SerializeField] private Vector2 focusMinBounds = new(30.2f, -5f);
|
||||
[SerializeField] private Vector2 focusMaxBounds = new(50.2f, 5f);
|
||||
|
||||
[Header("Visual Tuning")]
|
||||
[SerializeField] private EyeVisualSettings visualSettings = new();
|
||||
|
||||
[Tooltip("Play 模式下改 Visual Tuning 后,自动对当前目标重播一次 Focused 效果(如 ColorIn)。")]
|
||||
[SerializeField] private bool replayFocusedEffectOnSettingsChange = true;
|
||||
|
||||
public EyeVisualSettings VisualSettings => visualSettings;
|
||||
|
||||
private IEyeStateEffect eyeStateEffect;
|
||||
private EyeColorState _currentState = EyeColorState.CannotImagineColor;
|
||||
private MouseFollowAndZoom mouseFollowAndZoom;
|
||||
private Sequence glitchin;
|
||||
|
||||
/// <summary>获取当前 Eye 颜色阶段。</summary>
|
||||
public EyeColorState GetCurrentColorState() => _currentState;
|
||||
|
||||
public float GetEffectTransitionDuration() => visualSettings.GetDurationForState(_currentState);
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
ApplyVisualSettingsNow(
|
||||
previewIdleState: !Application.isPlaying,
|
||||
replayFocusedEffect: Application.isPlaying && replayFocusedEffectOnSettingsChange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将 Visual Tuning 推送到所有 EyeTarget。Edit 模式预览 idle;Play 模式可选重播当前目标效果。
|
||||
/// </summary>
|
||||
public void ApplyVisualSettingsNow(bool previewIdleState = false, bool replayFocusedEffect = false)
|
||||
{
|
||||
if (targets == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
target.BindVisualSettings(visualSettings);
|
||||
if (previewIdleState)
|
||||
{
|
||||
target.ApplyIdlePreviewState();
|
||||
}
|
||||
}
|
||||
|
||||
if (!replayFocusedEffect || !Application.isPlaying || currentTarget == null || eyeStateEffect == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
currentTarget.KillVisualTweens();
|
||||
eyeStateEffect.ApplyFocusedEffect(currentTarget, this);
|
||||
}
|
||||
|
||||
private void ApplyVisualSettingsToTargets()
|
||||
{
|
||||
ApplyVisualSettingsNow();
|
||||
}
|
||||
|
||||
public enum EyeColorState
|
||||
{
|
||||
CanImagineColor,
|
||||
@@ -42,37 +104,6 @@ namespace AibisDream
|
||||
HaveChip
|
||||
}
|
||||
|
||||
private Tween hsvShiftTween;
|
||||
private MouseFollowAndZoom mouseFollowAndZoom;
|
||||
private RenderTexture runtimeEyeRenderTexture;
|
||||
|
||||
/// <summary>
|
||||
/// 眼睛 RawImage 的故障/色相/饱和度等效果依赖 AllIn1SpriteShader(或兼容)材质上的属性。
|
||||
/// 若未在 Inspector 指定 Material,Unity 会使用 Default UI Material(UI/Default),不含 _HsvShift 等属性。
|
||||
/// </summary>
|
||||
private bool TryGetEyeImageMaterialForEffects(out Material material)
|
||||
{
|
||||
material = null;
|
||||
if (eyeImage == null)
|
||||
{
|
||||
Debug.LogError("[EyeSystem] eyeImage 未赋值。", this);
|
||||
return false;
|
||||
}
|
||||
|
||||
material = eyeImage.material;
|
||||
if (material == null || !material.HasProperty("_HsvShift"))
|
||||
{
|
||||
Debug.LogError(
|
||||
"[EyeSystem] eyeImage 需要指定 AllIn1SpriteShader(或兼容)材质;当前为 " +
|
||||
(material != null && material.shader != null ? material.shader.name : "null") +
|
||||
"。请在场景中选中该 RawImage,指定项目内 EyeMaterials / AllIn1 材质,勿留空(否则会使用 Default UI Material)。",
|
||||
this);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Init();
|
||||
@@ -95,96 +126,47 @@ namespace AibisDream
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool EnsureEyeViewRenderTarget()
|
||||
private Vector2 GetFocusViewportSize()
|
||||
{
|
||||
if (eyeImage == null)
|
||||
var focusCamera = Camera.main;
|
||||
if (focusCamera == null || !focusCamera.orthographic)
|
||||
{
|
||||
Debug.LogError("[EyeSystem] eyeImage 未赋值,无法显示视觉模块画面。", this);
|
||||
return false;
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
if (cameraManager == null)
|
||||
{
|
||||
Debug.LogError("[EyeSystem] cameraManager 未赋值,无法渲染视觉模块画面。", this);
|
||||
return false;
|
||||
}
|
||||
|
||||
var viewCamera = cameraManager.GetComponent<Camera>();
|
||||
if (viewCamera == null)
|
||||
{
|
||||
Debug.LogError("[EyeSystem] cameraManager 上未找到 Camera 组件,无法渲染视觉模块画面。", cameraManager);
|
||||
return false;
|
||||
}
|
||||
|
||||
viewCamera.allowHDR = false;
|
||||
viewCamera.allowMSAA = false;
|
||||
|
||||
var renderTexture = viewCamera.targetTexture;
|
||||
if (renderTexture == null)
|
||||
{
|
||||
renderTexture = CreateRuntimeEyeRenderTexture();
|
||||
viewCamera.targetTexture = renderTexture;
|
||||
}
|
||||
|
||||
if (!renderTexture.IsCreated())
|
||||
{
|
||||
renderTexture.Create();
|
||||
}
|
||||
|
||||
if (eyeImage.texture != renderTexture)
|
||||
{
|
||||
eyeImage.texture = renderTexture;
|
||||
}
|
||||
|
||||
return true;
|
||||
float height = focusCamera.orthographicSize * 2f;
|
||||
return new Vector2(height * focusCamera.aspect, height);
|
||||
}
|
||||
|
||||
private RenderTexture CreateRuntimeEyeRenderTexture()
|
||||
private static Transform GetFocusTransform(EyeTarget target)
|
||||
{
|
||||
var width = Mathf.Clamp(Screen.width, 1, 2048);
|
||||
var height = Mathf.Clamp(Screen.height, 1, 2048);
|
||||
|
||||
runtimeEyeRenderTexture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32)
|
||||
if (target == null)
|
||||
{
|
||||
name = "Runtime Eye View RenderTexture",
|
||||
antiAliasing = 1,
|
||||
useMipMap = false,
|
||||
autoGenerateMips = false
|
||||
};
|
||||
runtimeEyeRenderTexture.Create();
|
||||
return runtimeEyeRenderTexture;
|
||||
return null;
|
||||
}
|
||||
|
||||
return target.targetTransform ? target.targetTransform : target.transform;
|
||||
}
|
||||
|
||||
private IEnumerator PrimeEyeViewRender()
|
||||
public void FocusOnTarget(EyeTarget target, float duration)
|
||||
{
|
||||
yield return null;
|
||||
ForceRenderEyeView();
|
||||
yield return new WaitForEndOfFrame();
|
||||
ForceRenderEyeView();
|
||||
}
|
||||
|
||||
private void ForceRenderEyeView()
|
||||
{
|
||||
if (cameraManager == null || !cameraManager.gameObject.activeInHierarchy)
|
||||
Transform focusTransform = GetFocusTransform(target);
|
||||
if (focusTransform == null || !EnsureMouseFollowAndZoom())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var viewCamera = cameraManager.GetComponent<Camera>();
|
||||
if (viewCamera != null && viewCamera.enabled && viewCamera.targetTexture != null)
|
||||
{
|
||||
viewCamera.Render();
|
||||
}
|
||||
mouseFollowAndZoom.MoveFocusTo(
|
||||
focusTransform,
|
||||
duration,
|
||||
focusMinBounds,
|
||||
focusMaxBounds,
|
||||
GetFocusViewportSize());
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
FixSystemCenter.SystemDic.Register(this);
|
||||
|
||||
if (cameraManager != null)
|
||||
{
|
||||
cameraManager.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public EyeSnapshotDto CaptureEyeSnapshot()
|
||||
@@ -212,38 +194,28 @@ namespace AibisDream
|
||||
return;
|
||||
}
|
||||
|
||||
// 先激活 ViewCamera
|
||||
if (cameraManager != null)
|
||||
{
|
||||
cameraManager.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
EnsureEyeViewRenderTarget();
|
||||
|
||||
mouseFollowAndZoom.SetIsActive(true);
|
||||
mouseFollowAndZoom.SetIsLock(false);
|
||||
// 激活 ViewCamera 后再打开 EyeView
|
||||
OpenEyeView();
|
||||
ForceRenderEyeView();
|
||||
StartCoroutine(PrimeEyeViewRender());
|
||||
// 进入视图时的逻辑
|
||||
Debug.Log("EyeView entered.");
|
||||
mouseFollowAndZoom.ResetPanOrigin();
|
||||
ApplyVisualSettingsToTargets();
|
||||
InitializeAllTargets();
|
||||
}
|
||||
|
||||
public void OpenEyeView()
|
||||
private void InitializeAllTargets()
|
||||
{
|
||||
eyeView.SetActive(true);
|
||||
}
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
target.Init();
|
||||
}
|
||||
|
||||
public void CloseEyeView()
|
||||
{
|
||||
eyeView.SetActive(false);
|
||||
if (currentTarget != null)
|
||||
{
|
||||
eyeStateEffect?.InitializeEffect(currentTarget, this);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnShow()
|
||||
{
|
||||
// 离开视图时的逻辑
|
||||
Debug.Log("EyeView showed.");
|
||||
}
|
||||
|
||||
public void OnExit()
|
||||
@@ -259,31 +231,12 @@ namespace AibisDream
|
||||
}
|
||||
|
||||
currentTarget = null;
|
||||
// 先关闭 EyeView
|
||||
CloseEyeView();
|
||||
// 再关闭 ViewCamera
|
||||
if (cameraManager != null)
|
||||
{
|
||||
cameraManager.gameObject.SetActive(false);
|
||||
}
|
||||
// 离开视图时的逻辑
|
||||
Debug.Log("EyeView exited.");
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (runtimeEyeRenderTexture != null)
|
||||
{
|
||||
runtimeEyeRenderTexture.Release();
|
||||
Destroy(runtimeEyeRenderTexture);
|
||||
runtimeEyeRenderTexture = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
ApplyVisualSettingsToTargets();
|
||||
SetEyeColorState(_currentState);
|
||||
|
||||
EnsureMouseFollowAndZoom();
|
||||
}
|
||||
|
||||
@@ -320,13 +273,13 @@ namespace AibisDream
|
||||
}
|
||||
|
||||
YarnVariableStorage.Instance.SetValue("$currentEyeTarget", target.name);
|
||||
StartCoroutine(EyeEffectFadeOut());
|
||||
StartCoroutine(EyeEffect_FadeOut());
|
||||
|
||||
cameraManager.MoveCameraTo(target.targetTransform ? target.targetTransform : target.transform, 1f);
|
||||
FocusOnTarget(target, 1f);
|
||||
|
||||
if (currentTarget != null)
|
||||
{
|
||||
currentTarget.BlurIn(eyeStateEffect.TransitionDuration, false);
|
||||
currentTarget.BlurIn(visualSettings.targetSwitchDuration);
|
||||
}
|
||||
|
||||
if (currentTarget == target)
|
||||
@@ -334,16 +287,16 @@ namespace AibisDream
|
||||
DialogController.Instance.StartDialogNode("重复看同一个目标");
|
||||
currentTarget = target;
|
||||
mouseFollowAndZoom.SetIndicatorTarget(currentTarget);
|
||||
currentTarget.BlurOut(eyeStateEffect.TransitionDuration, false);
|
||||
yield return new WaitForSeconds(eyeStateEffect.TransitionDuration);
|
||||
currentTarget.BlurOut(visualSettings.targetSwitchDuration);
|
||||
yield return new WaitForSeconds(visualSettings.targetSwitchDuration);
|
||||
yield break;
|
||||
}
|
||||
|
||||
currentTarget = target;
|
||||
mouseFollowAndZoom.SetIndicatorTarget(currentTarget);
|
||||
currentTarget.BlurOut(eyeStateEffect.TransitionDuration, false);
|
||||
currentTarget.BlurOut(visualSettings.targetSwitchDuration);
|
||||
|
||||
yield return new WaitForSeconds(eyeStateEffect.TransitionDuration);
|
||||
yield return new WaitForSeconds(visualSettings.targetSwitchDuration);
|
||||
|
||||
if (startDialogue)
|
||||
{
|
||||
@@ -363,44 +316,34 @@ namespace AibisDream
|
||||
}
|
||||
|
||||
[YarnCommand("EyeEffect_FadeIn")]
|
||||
public IEnumerator EyeEffectFadeIn()
|
||||
public IEnumerator EyeEffect_FadeIn()
|
||||
{
|
||||
if (currentTarget != null)
|
||||
{
|
||||
// AudioManager.RandomPlayInteraction("colorimagine");
|
||||
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
|
||||
|
||||
eyeStateEffect?.ApplyFocusedEffect(currentTarget);
|
||||
eyeStateEffect?.ApplyFocusedEffect(currentTarget, this);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(eyeStateEffect.TransitionDuration);
|
||||
yield return new WaitForSeconds(GetEffectTransitionDuration());
|
||||
}
|
||||
|
||||
[YarnCommand("EyeEffect_FadeOut")]
|
||||
public IEnumerator EyeEffectFadeOut()
|
||||
public IEnumerator EyeEffect_FadeOut()
|
||||
{
|
||||
if (currentTarget != null)
|
||||
{
|
||||
// AudioManager.RandomPlayInteraction("colorimagine");
|
||||
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
|
||||
eyeStateEffect?.ApplyUnfocusedEffect(currentTarget);
|
||||
eyeStateEffect?.ApplyUnfocusedEffect(currentTarget, this);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(eyeStateEffect.TransitionDuration);
|
||||
yield return new WaitForSeconds(GetEffectTransitionDuration());
|
||||
}
|
||||
|
||||
[YarnCommand("EyeEffect_Init")]
|
||||
public void EyeEffectInit()
|
||||
{
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
target.Init();
|
||||
}
|
||||
|
||||
if (currentTarget != null)
|
||||
{
|
||||
eyeStateEffect?.InitializeEffect(currentTarget, cameraManager);
|
||||
}
|
||||
ApplyVisualSettingsToTargets();
|
||||
InitializeAllTargets();
|
||||
}
|
||||
|
||||
[YarnCommand("EyeEffect_Clean")]
|
||||
@@ -415,127 +358,71 @@ namespace AibisDream
|
||||
[YarnCommand("set_EyeColorState")]
|
||||
public void SetEyeColorStateForYarn(string state)
|
||||
{
|
||||
// Try to parse the string as an EyeColorState
|
||||
if (!Enum.TryParse(state, true, out EyeColorState eyeState))
|
||||
{
|
||||
throw new ArgumentException("Invalid eye state: " + state, nameof(state));
|
||||
}
|
||||
|
||||
// Start the coroutine for setting the eye state
|
||||
SetEyeColorState(eyeState);
|
||||
}
|
||||
|
||||
private void SetEyeColorState(EyeColorState state)
|
||||
{
|
||||
_currentState = state;
|
||||
switch (state)
|
||||
eyeStateEffect = state switch
|
||||
{
|
||||
case EyeColorState.CanImagineColor:
|
||||
eyeStateEffect = new CanImagineColorEffect();
|
||||
break;
|
||||
case EyeColorState.CannotImagineColor:
|
||||
eyeStateEffect = new CannotImagineColorEffect();
|
||||
break;
|
||||
case EyeColorState.EyeDisorder:
|
||||
eyeStateEffect = new EyeDisorderEffect();
|
||||
break;
|
||||
case EyeColorState.CanSeeColor:
|
||||
eyeStateEffect = new CanSeeColorEffect();
|
||||
break;
|
||||
case EyeColorState.HaveChip:
|
||||
eyeStateEffect = new HaveChip();
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unknown eye state: " + state.ToString(), nameof(state));
|
||||
}
|
||||
EyeColorState.CanImagineColor => new CanImagineColorEffect(),
|
||||
EyeColorState.CannotImagineColor => new CannotImagineColorEffect(),
|
||||
EyeColorState.EyeDisorder => new EyeDisorderEffect(),
|
||||
EyeColorState.CanSeeColor => new CanSeeColorEffect(),
|
||||
EyeColorState.HaveChip => new HaveChip(),
|
||||
_ => throw new ArgumentException("Unknown eye state: " + state, nameof(state))
|
||||
};
|
||||
}
|
||||
|
||||
[YarnCommand("Set_Saturation")]
|
||||
public IEnumerator Set_Saturation(float targetSaturation, float duration)
|
||||
{
|
||||
if (!TryGetEyeImageMaterialForEffects(out Material material))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
// 确保 targetSaturation 在 0 到 1 之间
|
||||
targetSaturation = Mathf.Clamp01(targetSaturation);
|
||||
|
||||
Sequence saturationSequence = DOTween.Sequence();
|
||||
if (!TryJoinTargetSaturation(saturationSequence, targetSaturation, duration))
|
||||
{
|
||||
Debug.LogWarning("[EyeSystem] 无可用 EyeTarget 饱和度 tween。", this);
|
||||
yield break;
|
||||
}
|
||||
|
||||
// 同时启动材质的饱和度变化和 Volume 的weight变化
|
||||
saturationSequence.Join(material.DOFloat(targetSaturation, "_HsvSaturation", duration));
|
||||
|
||||
// 获取 Tween 对象并添加到序列中
|
||||
Tween saturationTween = ScreenEffectManager.Instance.TweenSaturation(targetSaturation, duration);
|
||||
Tween saturationTween = ScreenEffectManager.Instance != null
|
||||
? ScreenEffectManager.Instance.TweenSaturation(targetSaturation, duration)
|
||||
: null;
|
||||
if (saturationTween != null)
|
||||
{
|
||||
saturationSequence.Join(saturationTween);
|
||||
}
|
||||
|
||||
// 启动 Sequence 并等待完成
|
||||
yield return saturationSequence.WaitForCompletion();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Sequence glitchin;
|
||||
|
||||
[YarnCommand("EyeGlitch_in")]
|
||||
public IEnumerator EyeGlitch_in()
|
||||
{
|
||||
if (!TryGetEyeImageMaterialForEffects(out Material material))
|
||||
if (!TryStartUnifiedGlitch())
|
||||
{
|
||||
yield break;
|
||||
Debug.LogWarning("[EyeSystem] 无可用 EyeTarget Glitch tween。", this);
|
||||
}
|
||||
|
||||
glitchin = DOTween.Sequence();
|
||||
// _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);
|
||||
yield return new WaitForSeconds(visualSettings.glitchInDuration);
|
||||
}
|
||||
|
||||
[YarnCommand("EyeGlitch_out")]
|
||||
public void EyeGlitch_out(float duration)
|
||||
{
|
||||
if (!TryGetEyeImageMaterialForEffects(out Material material))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (glitchin != null && glitchin.IsActive())
|
||||
{
|
||||
glitchin.Kill();
|
||||
}
|
||||
|
||||
material.DOFloat(0, "_WarpStrength", duration);
|
||||
material.DOFloat(0, "_GlitchAmount", duration);
|
||||
material.DOFloat(0, "_HsvShift", duration);
|
||||
// 确保之前的动画被停止
|
||||
TryStopUnifiedGlitch(duration > 0f ? duration : visualSettings.glitchOutDuration);
|
||||
}
|
||||
|
||||
[YarnCommand("set_EyeColor")]
|
||||
public IEnumerator SetEyeColor(string color, string memoryName = null)
|
||||
{
|
||||
if (!TryGetEyeImageMaterialForEffects(out Material material))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (memoryRender == null)
|
||||
{
|
||||
Debug.LogError("[EyeSystem] memoryRender 未赋值。", this);
|
||||
@@ -559,63 +446,37 @@ namespace AibisDream
|
||||
}
|
||||
|
||||
memoryRender.sprite = memoryHandle.Result;
|
||||
// 使 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())
|
||||
|
||||
Sequence waveIn = CreateTargetRoundWaveSequence(1f, visualSettings.roundWaveInDuration);
|
||||
if (waveIn != null)
|
||||
{
|
||||
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;
|
||||
sequence.Append(waveIn);
|
||||
}
|
||||
|
||||
// 添加一个 tween 来将 _RoundWaveStrength 的值回复为 0
|
||||
sequence.Append(material.DOFloat(0, "_RoundWaveStrength", 0.5f));
|
||||
sequence.AppendCallback(() => { EyeGlitch_out(visualSettings.glitchOutDuration); });
|
||||
|
||||
Sequence waveOut = CreateTargetRoundWaveSequence(0f, visualSettings.roundWaveOutDuration);
|
||||
if (waveOut != null)
|
||||
{
|
||||
sequence.Append(waveOut);
|
||||
}
|
||||
|
||||
// 开始这个序列
|
||||
sequence.Play();
|
||||
|
||||
// 等待序列完成
|
||||
yield return sequence.WaitForCompletion();
|
||||
}
|
||||
|
||||
@@ -623,13 +484,118 @@ namespace AibisDream
|
||||
public void GetColor()
|
||||
{
|
||||
SetEyeColorState(EyeColorState.CanImagineColor);
|
||||
// 对目标列表中的每个目标执行 ColorBack 方法
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
target.ColorBack();
|
||||
}
|
||||
}
|
||||
|
||||
// 切换到 CanImagineColorEffect 状态
|
||||
public void SetUnifiedUfWeights(float ascii, float dream, float memory)
|
||||
{
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
target.SetUfWeights(ascii, dream, memory);
|
||||
}
|
||||
}
|
||||
|
||||
public Tween TweenUnifiedUfWeights(float ascii, float dream, float memory, float duration)
|
||||
{
|
||||
Sequence sequence = DOTween.Sequence();
|
||||
bool hasTween = false;
|
||||
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
Tween tween = target.TweenUfWeights(ascii, dream, memory, duration);
|
||||
if (tween == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sequence.Join(tween);
|
||||
hasTween = true;
|
||||
}
|
||||
|
||||
return hasTween ? sequence : null;
|
||||
}
|
||||
|
||||
private bool TryJoinTargetSaturation(Sequence sequence, float saturation, float duration)
|
||||
{
|
||||
bool hasTween = false;
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
Tween tween = target.TweenSaturation(saturation, duration);
|
||||
if (tween == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sequence.Join(tween);
|
||||
hasTween = true;
|
||||
}
|
||||
|
||||
return hasTween;
|
||||
}
|
||||
|
||||
private bool TryStartUnifiedGlitch()
|
||||
{
|
||||
glitchin?.Kill();
|
||||
glitchin = DOTween.Sequence();
|
||||
bool hasTween = false;
|
||||
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
Sequence targetGlitch = target.StartUnifiedGlitch(visualSettings.glitchInDuration);
|
||||
if (targetGlitch == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
glitchin.Join(targetGlitch);
|
||||
hasTween = true;
|
||||
}
|
||||
|
||||
return hasTween;
|
||||
}
|
||||
|
||||
private bool TryStopUnifiedGlitch(float duration)
|
||||
{
|
||||
bool hasTarget = false;
|
||||
if (glitchin != null && glitchin.IsActive())
|
||||
{
|
||||
glitchin.Kill();
|
||||
hasTarget = true;
|
||||
}
|
||||
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
if (!target.TryGetUnifiedVisual(out _))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
target.StopUnifiedGlitch(duration);
|
||||
hasTarget = true;
|
||||
}
|
||||
|
||||
return hasTarget;
|
||||
}
|
||||
|
||||
private Sequence CreateTargetRoundWaveSequence(float value, float duration)
|
||||
{
|
||||
Sequence sequence = DOTween.Sequence();
|
||||
bool hasTween = false;
|
||||
|
||||
foreach (EyeTarget target in targets)
|
||||
{
|
||||
Tween tween = target.TweenRoundWave(value, duration);
|
||||
if (tween != null)
|
||||
{
|
||||
sequence.Join(tween);
|
||||
hasTween = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasTween ? sequence : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,149 +1,315 @@
|
||||
using UnityEngine;
|
||||
using DG.Tweening;
|
||||
using AibisDream.Utility;
|
||||
using AibisDream;
|
||||
using AibisDream.Kit;
|
||||
using AibisDream.Utility;
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
|
||||
public class EyeTarget : MonoBehaviour
|
||||
{
|
||||
public Transform targetTransform; // EyeTarget的位置
|
||||
[SerializeField] private float burnRadiusMin = 0f; // 对应_BurnRadius的最小值
|
||||
public Transform targetTransform;
|
||||
|
||||
[SerializeField] private float burnRadiusMax = 1f; // 对应_BurnRadius的最大值
|
||||
|
||||
private Material forwardMaterial;
|
||||
|
||||
[SerializeField] private SpriteRenderer backSpriteRenderer;
|
||||
|
||||
[SerializeField] private SpriteRenderer wrongColorSpriteRenderer;
|
||||
[Header("Optional overlay sprite for UF imagination")]
|
||||
[SerializeField] private SpriteRenderer imageSpriteRender;
|
||||
private Material backMaterial;
|
||||
private Material wrongColorMaterial;
|
||||
|
||||
[SerializeField] private Shader unifiedSpriteShader;
|
||||
[SerializeField] private EyeTargetVisual unifiedVisual;
|
||||
|
||||
public Color _color;
|
||||
|
||||
private EyeVisualSettings visualSettings = new();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 获取此对象的材质
|
||||
SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
|
||||
forwardMaterial = spriteRenderer.material;
|
||||
forwardMaterial.SetFloat("_SourceGlowDissolveFade", burnRadiusMin);
|
||||
var spriteRenderer = GetComponent<SpriteRenderer>();
|
||||
if (spriteRenderer == null)
|
||||
{
|
||||
Debug.LogError($"[EyeTarget] {name} 缺少 SpriteRenderer。", this);
|
||||
return;
|
||||
}
|
||||
|
||||
backMaterial = backSpriteRenderer.material;
|
||||
wrongColorMaterial = wrongColorSpriteRenderer.material;
|
||||
;
|
||||
EnsureUnifiedVisual(spriteRenderer);
|
||||
DisableLegacyChildRenderers();
|
||||
DisableLegacySiblingRenderers();
|
||||
}
|
||||
|
||||
public void BindVisualSettings(EyeVisualSettings settings)
|
||||
{
|
||||
visualSettings = settings ?? new EyeVisualSettings();
|
||||
RefreshMaterialTuning();
|
||||
}
|
||||
|
||||
public void RefreshMaterialTuning()
|
||||
{
|
||||
EnsureVisualReady();
|
||||
unifiedVisual?.ApplyTuning(visualSettings);
|
||||
}
|
||||
|
||||
public void ApplyIdlePreviewState()
|
||||
{
|
||||
EnsureVisualReady();
|
||||
Init();
|
||||
}
|
||||
|
||||
public void KillVisualTweens()
|
||||
{
|
||||
unifiedVisual?.KillActiveTweens();
|
||||
}
|
||||
|
||||
private void EnsureVisualReady()
|
||||
{
|
||||
var spriteRenderer = GetComponent<SpriteRenderer>();
|
||||
if (spriteRenderer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (unifiedVisual == null || !unifiedVisual.IsReady)
|
||||
{
|
||||
EnsureUnifiedVisual(spriteRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
SetToMinBurnRadius();
|
||||
SetToMaxBlur(false);
|
||||
SetToMinColorReveal();
|
||||
SetToMaxBlur();
|
||||
SetToNoWrongColor();
|
||||
SetNoImage();
|
||||
}
|
||||
|
||||
public void ImageIn(float duration)
|
||||
{
|
||||
imageSpriteRender.DOFade(1, duration);
|
||||
unifiedVisual?.TweenImageAlpha(1f, duration);
|
||||
}
|
||||
|
||||
public void ImageOut(float duration)
|
||||
{
|
||||
imageSpriteRender.DOFade(0, duration);
|
||||
unifiedVisual?.TweenImageAlpha(0f, duration);
|
||||
}
|
||||
|
||||
public void SetNoImage()
|
||||
{
|
||||
imageSpriteRender.SetAlpha(0);
|
||||
unifiedVisual?.SetImageAlpha(0f);
|
||||
}
|
||||
|
||||
public void SetToMinBurnRadius()
|
||||
public void SetToMinColorReveal()
|
||||
{
|
||||
forwardMaterial.SetFloat("_SourceGlowDissolveFade", burnRadiusMin);
|
||||
unifiedVisual?.SetColorReveal(visualSettings.colorRevealMin);
|
||||
}
|
||||
|
||||
public void SetToMaxBurnRadius()
|
||||
public void SetToMaxColorReveal()
|
||||
{
|
||||
forwardMaterial.SetFloat("_SourceGlowDissolveFade", burnRadiusMax);
|
||||
unifiedVisual?.SetColorReveal(visualSettings.colorRevealMax);
|
||||
}
|
||||
|
||||
public void SetToMaxBlur(bool isForwardMaterial = true)
|
||||
public void SetToMaxBlur()
|
||||
{
|
||||
Material targetMaterial = isForwardMaterial ? forwardMaterial : backMaterial;
|
||||
targetMaterial.SetFloat("_GaussianBlurFade", 1f);
|
||||
unifiedVisual?.SetBlur(visualSettings.idleBlurAmount);
|
||||
}
|
||||
|
||||
public void SetToMinBlur(bool isForwardMaterial = true)
|
||||
public void SetToMinBlur()
|
||||
{
|
||||
Material targetMaterial = isForwardMaterial ? forwardMaterial : backMaterial;
|
||||
targetMaterial.SetFloat("_GaussianBlurFade", 0f);
|
||||
unifiedVisual?.SetBlur(visualSettings.focusedBlurAmount);
|
||||
}
|
||||
|
||||
public void SetToNoWrongColor()
|
||||
{
|
||||
wrongColorMaterial.SetFloat("_Alpha", 0f);
|
||||
unifiedVisual?.SetWrongColor(0f);
|
||||
}
|
||||
|
||||
public void SetToWrongColor()
|
||||
{
|
||||
wrongColorMaterial.SetFloat("_Alpha", 1f);
|
||||
unifiedVisual?.SetWrongColor(1f);
|
||||
}
|
||||
|
||||
public void FadeOut(float duration)
|
||||
{
|
||||
// 使用DoTween库来改变_BurnRadius,使目标褪色
|
||||
forwardMaterial.DOFloat(burnRadiusMin, "_SourceGlowDissolveFade", duration);
|
||||
forwardMaterial.DOFloat(1f, "_GaussianBlurFade", duration).SetEase(Ease.InSine);
|
||||
forwardMaterial.DOFloat(1f, "_UVDistortFade", duration / 2).SetEase(Ease.InSine).SetLoops(2, LoopType.Yoyo);
|
||||
;
|
||||
unifiedVisual?.TweenColorReveal(visualSettings.colorRevealMin, duration)?.SetEase(Ease.InSine);
|
||||
unifiedVisual?.TweenBlur(visualSettings.idleBlurAmount, duration)?.SetEase(Ease.InSine);
|
||||
unifiedVisual?.PulseDistortion(visualSettings.colorPulseDistortion, duration);
|
||||
}
|
||||
|
||||
public void ColorIn(float duration)
|
||||
{
|
||||
forwardMaterial.DOFloat(burnRadiusMax, "_SourceGlowDissolveFade", duration).SetEase(Ease.InOutSine);
|
||||
forwardMaterial.DOFloat(0f, "_GaussianBlurFade", duration).SetEase(Ease.InOutSine);
|
||||
forwardMaterial.DOFloat(1f, "_UVDistortFade", duration / 2).SetEase(Ease.InOutSine).SetLoops(2, LoopType.Yoyo);
|
||||
;
|
||||
unifiedVisual?.TweenColorReveal(visualSettings.colorRevealMax, duration)?.SetEase(Ease.InOutSine);
|
||||
unifiedVisual?.TweenBlur(visualSettings.focusedBlurAmount, duration)?.SetEase(Ease.InOutSine);
|
||||
unifiedVisual?.PulseDistortion(visualSettings.colorPulseDistortion, duration);
|
||||
}
|
||||
|
||||
public void WrongColorIn(float duration)
|
||||
{
|
||||
wrongColorMaterial.DOFloat(1f, "_Alpha", duration).SetEase(Ease.InOutSine);
|
||||
unifiedVisual?.TweenWrongColor(1f, duration)?.SetEase(Ease.InOutSine);
|
||||
}
|
||||
|
||||
public void WrongColorOut(float duration)
|
||||
{
|
||||
wrongColorMaterial.DOFloat(0f, "_Alpha", duration).SetEase(Ease.InOutSine);
|
||||
unifiedVisual?.TweenWrongColor(0f, duration)?.SetEase(Ease.InOutSine);
|
||||
}
|
||||
|
||||
public void BlurIn(float duration, bool isForwardMaterial = true)
|
||||
public void BlurIn(float duration)
|
||||
{
|
||||
// AudioManager.PlayLoopAudio("visualturn");
|
||||
AudioManager.Instance.PlaySfx("event:/ActionFB/visualturn");
|
||||
Material targetMaterial = isForwardMaterial ? forwardMaterial : backMaterial;
|
||||
targetMaterial.DOFloat(1f, "_GaussianBlurFade", duration).SetEase(Ease.InOutSine)
|
||||
.OnComplete(() => { AudioManager.Instance.StopSfx("event:/ActionFB/visualturn"); });
|
||||
var tween = unifiedVisual?.TweenBlur(visualSettings.idleBlurAmount, duration);
|
||||
tween?.SetEase(Ease.InOutSine).OnComplete(StopVisualTurnSfx);
|
||||
}
|
||||
|
||||
public void BlurOut(float duration, bool isForwardMaterial = true)
|
||||
public void BlurOut(float duration)
|
||||
{
|
||||
// AudioManager.PlayLoopAudio("visualturn");
|
||||
AudioManager.Instance.PlaySfx("event:/ActionFB/visualturn");
|
||||
Material targetMaterial = isForwardMaterial ? forwardMaterial : backMaterial;
|
||||
targetMaterial.DOFloat(0f, "_GaussianBlurFade", duration).SetEase(Ease.InOutSine)
|
||||
.OnComplete(() => { AudioManager.Instance.StopSfx("event:/ActionFB/visualturn"); });
|
||||
var tween = unifiedVisual?.TweenBlur(visualSettings.focusedBlurAmount, duration);
|
||||
tween?.SetEase(Ease.InOutSine).OnComplete(StopVisualTurnSfx);
|
||||
}
|
||||
|
||||
public void ColorBack()
|
||||
{
|
||||
SetToMaxBurnRadius();
|
||||
SetToMaxColorReveal();
|
||||
SetToNoWrongColor();
|
||||
SetToMinBlur();
|
||||
}
|
||||
|
||||
public void ColorLost()
|
||||
{
|
||||
SetToMinBurnRadius();
|
||||
//SetToNoWrongColor();
|
||||
SetToMinColorReveal();
|
||||
SetToMaxBlur();
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetUnifiedVisual(out EyeTargetVisual visual)
|
||||
{
|
||||
visual = unifiedVisual;
|
||||
return visual != null && visual.IsReady;
|
||||
}
|
||||
|
||||
public void SetSaturation(float saturation)
|
||||
{
|
||||
unifiedVisual?.SetSaturation(saturation);
|
||||
}
|
||||
|
||||
public Tween TweenSaturation(float saturation, float duration)
|
||||
{
|
||||
return unifiedVisual != null ? unifiedVisual.TweenSaturation(saturation, duration) : null;
|
||||
}
|
||||
|
||||
public DG.Tweening.Sequence StartUnifiedGlitch(float duration = 1f)
|
||||
{
|
||||
return unifiedVisual != null ? unifiedVisual.StartGlitch(duration) : null;
|
||||
}
|
||||
|
||||
public void StopUnifiedGlitch(float duration)
|
||||
{
|
||||
unifiedVisual?.StopGlitch(duration);
|
||||
}
|
||||
|
||||
public Tween TweenRoundWave(float value, float duration)
|
||||
{
|
||||
return unifiedVisual != null ? unifiedVisual.TweenRoundWave(value, duration) : null;
|
||||
}
|
||||
|
||||
public void SetUfWeights(float ascii, float dream, float memory)
|
||||
{
|
||||
unifiedVisual?.SetUfWeights(ascii, dream, memory);
|
||||
}
|
||||
|
||||
public Tween TweenUfWeights(float ascii, float dream, float memory, float duration)
|
||||
{
|
||||
return unifiedVisual != null ? unifiedVisual.TweenUfWeights(ascii, dream, memory, duration) : null;
|
||||
}
|
||||
|
||||
private void EnsureUnifiedVisual(SpriteRenderer spriteRenderer)
|
||||
{
|
||||
Shader shader = unifiedSpriteShader != null
|
||||
? unifiedSpriteShader
|
||||
: Shader.Find("AIBIS/EyeUnifiedSprite");
|
||||
if (shader == null)
|
||||
{
|
||||
Debug.LogError($"[EyeTarget] 找不到 AIBIS/EyeUnifiedSprite shader:{name}", this);
|
||||
return;
|
||||
}
|
||||
|
||||
Material currentMaterial = spriteRenderer.material;
|
||||
bool usesUnifiedShader = currentMaterial != null
|
||||
&& currentMaterial.shader != null
|
||||
&& currentMaterial.shader.name == shader.name;
|
||||
if (currentMaterial == null || !usesUnifiedShader || !currentMaterial.HasProperty("_BlurAmount"))
|
||||
{
|
||||
Texture mainTex = currentMaterial != null && currentMaterial.HasProperty("_MainTex")
|
||||
? currentMaterial.GetTexture("_MainTex")
|
||||
: null;
|
||||
spriteRenderer.material = new Material(shader)
|
||||
{
|
||||
name = $"{gameObject.name}_EyeUnified_Runtime"
|
||||
};
|
||||
if (mainTex != null)
|
||||
{
|
||||
spriteRenderer.material.SetTexture("_MainTex", mainTex);
|
||||
}
|
||||
}
|
||||
|
||||
if (unifiedVisual == null)
|
||||
{
|
||||
unifiedVisual = GetComponent<EyeTargetVisual>();
|
||||
}
|
||||
|
||||
if (unifiedVisual == null)
|
||||
{
|
||||
unifiedVisual = gameObject.AddComponent<EyeTargetVisual>();
|
||||
}
|
||||
|
||||
unifiedVisual.Configure(spriteRenderer, imageSpriteRender);
|
||||
unifiedVisual.ApplyTuning(visualSettings);
|
||||
}
|
||||
|
||||
private void DisableLegacyChildRenderers()
|
||||
{
|
||||
foreach (var childRenderer in GetComponentsInChildren<SpriteRenderer>(true))
|
||||
{
|
||||
if (childRenderer.gameObject == gameObject)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (imageSpriteRender != null && childRenderer == imageSpriteRender)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
childRenderer.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 禁用同组下旧版 overlay(如 posterNoColor / computernocolor),避免盖住 unified 效果。
|
||||
/// </summary>
|
||||
private void DisableLegacySiblingRenderers()
|
||||
{
|
||||
Transform groupRoot = transform.parent;
|
||||
if (groupRoot == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var renderer in groupRoot.GetComponentsInChildren<SpriteRenderer>(true))
|
||||
{
|
||||
if (renderer.gameObject == gameObject)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (renderer.GetComponent<EyeTarget>() != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (renderer.GetComponentInParent<EyeTarget>() != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
renderer.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void StopVisualTurnSfx()
|
||||
{
|
||||
AudioManager.Instance.StopSfx("event:/ActionFB/visualturn");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,312 @@
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
using AibisDream.Utility;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
/// <summary>
|
||||
/// Drives the unified EyeUnifiedSprite path for Peipei eye targets.
|
||||
/// </summary>
|
||||
public class EyeTargetVisual : MonoBehaviour
|
||||
{
|
||||
private static readonly int ColorRevealId = Shader.PropertyToID("_ColorReveal");
|
||||
private static readonly int GrayAmountId = Shader.PropertyToID("_GrayAmount");
|
||||
private static readonly int BlurAmountId = Shader.PropertyToID("_BlurAmount");
|
||||
private static readonly int BlurSizeId = Shader.PropertyToID("_BlurSize");
|
||||
private static readonly int DistortAmountId = Shader.PropertyToID("_DistortAmount");
|
||||
private static readonly int WrongColorAmountId = Shader.PropertyToID("_WrongColorAmount");
|
||||
private static readonly int SpriteFadeId = Shader.PropertyToID("_SpriteFade");
|
||||
private static readonly int AsciiAmountId = Shader.PropertyToID("_AsciiAmount");
|
||||
private static readonly int DreamAmountId = Shader.PropertyToID("_DreamAmount");
|
||||
private static readonly int MemoryAmountId = Shader.PropertyToID("_MemoryAmount");
|
||||
private static readonly int ScanlineAmountId = Shader.PropertyToID("_ScanlineAmount");
|
||||
private static readonly int GlitchAmountId = Shader.PropertyToID("_GlitchAmount");
|
||||
private static readonly int HsvShiftId = Shader.PropertyToID("_HsvShift");
|
||||
private static readonly int HsvSaturationId = Shader.PropertyToID("_HsvSaturation");
|
||||
private static readonly int RoundWaveStrengthId = Shader.PropertyToID("_RoundWaveStrength");
|
||||
|
||||
private static readonly int RevealWidthId = Shader.PropertyToID("_RevealWidth");
|
||||
private static readonly int RevealRotationId = Shader.PropertyToID("_RevealRotation");
|
||||
private static readonly int RevealNoiseId = Shader.PropertyToID("_RevealNoise");
|
||||
private static readonly int WrongColorId = Shader.PropertyToID("_WrongColor");
|
||||
|
||||
[SerializeField] private SpriteRenderer spriteRenderer;
|
||||
[SerializeField] private SpriteRenderer imageSpriteRenderer;
|
||||
[SerializeField] private bool driveImageLayer = true;
|
||||
|
||||
private Material material;
|
||||
private float activeBlurSize = 0.008f;
|
||||
|
||||
public bool IsReady => material != null && material.HasProperty(ColorRevealId);
|
||||
public bool CanDriveImageLayer => driveImageLayer && imageSpriteRenderer != null;
|
||||
public Material Material => material;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
EnsureMaterial();
|
||||
}
|
||||
|
||||
public bool EnsureMaterial()
|
||||
{
|
||||
if (spriteRenderer == null)
|
||||
{
|
||||
spriteRenderer = GetComponent<SpriteRenderer>();
|
||||
}
|
||||
|
||||
if (spriteRenderer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
material = spriteRenderer.material;
|
||||
return IsReady;
|
||||
}
|
||||
|
||||
public void Configure(SpriteRenderer mainRenderer, SpriteRenderer imageRenderer)
|
||||
{
|
||||
spriteRenderer = mainRenderer;
|
||||
imageSpriteRenderer = imageRenderer;
|
||||
EnsureMaterial();
|
||||
}
|
||||
|
||||
public void ApplyTuning(EyeVisualSettings settings)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
activeBlurSize = settings.blurSize;
|
||||
|
||||
if (!EnsureMaterial())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
material.SetFloat(RevealWidthId, settings.revealWidth);
|
||||
material.SetFloat(RevealRotationId, settings.revealRotation);
|
||||
material.SetFloat(RevealNoiseId, settings.revealNoise);
|
||||
material.SetColor(WrongColorId, settings.wrongColor);
|
||||
SetFloatRaw(HsvSaturationId, settings.hsvSaturation);
|
||||
SyncBlurSizeToMaterial();
|
||||
}
|
||||
|
||||
public void SyncBlurSizeToMaterial()
|
||||
{
|
||||
if (!EnsureMaterial() || !material.HasProperty(BlurSizeId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float blur = material.GetFloat(BlurAmountId);
|
||||
material.SetFloat(BlurSizeId, blur > 0.01f ? activeBlurSize : 0f);
|
||||
}
|
||||
|
||||
public void KillActiveTweens()
|
||||
{
|
||||
if (material != null)
|
||||
{
|
||||
material.DOKill();
|
||||
}
|
||||
|
||||
if (driveImageLayer && imageSpriteRenderer != null)
|
||||
{
|
||||
imageSpriteRenderer.DOKill();
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetVisual(float reveal)
|
||||
{
|
||||
if (!EnsureMaterial())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetFloat(ColorRevealId, reveal);
|
||||
SetFloat(GrayAmountId, 1f - reveal);
|
||||
SetFloat(BlurAmountId, 1f);
|
||||
if (material.HasProperty(BlurSizeId))
|
||||
{
|
||||
material.SetFloat(BlurSizeId, activeBlurSize);
|
||||
}
|
||||
SetFloat(DistortAmountId, 0f);
|
||||
SetFloat(WrongColorAmountId, 0f);
|
||||
SetFloat(SpriteFadeId, 1f);
|
||||
SetFloat(AsciiAmountId, 0f);
|
||||
SetFloat(DreamAmountId, 0f);
|
||||
SetFloat(MemoryAmountId, 0f);
|
||||
SetFloat(ScanlineAmountId, 0f);
|
||||
SetFloat(GlitchAmountId, 0f);
|
||||
SetFloat(HsvShiftId, 0f);
|
||||
SetFloat(HsvSaturationId, 1f);
|
||||
SetFloat(RoundWaveStrengthId, 0f);
|
||||
SetImageAlpha(0f);
|
||||
}
|
||||
|
||||
public void SetColorReveal(float value)
|
||||
{
|
||||
SetFloat(ColorRevealId, value);
|
||||
SetFloat(GrayAmountId, 1f - value);
|
||||
}
|
||||
|
||||
public Tween TweenColorReveal(float value, float duration)
|
||||
{
|
||||
if (!EnsureMaterial())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
value = Mathf.Clamp01(value);
|
||||
Sequence sequence = DOTween.Sequence();
|
||||
sequence.Join(material.DOFloat(value, ColorRevealId, duration));
|
||||
sequence.Join(material.DOFloat(1f - value, GrayAmountId, duration));
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public void SetBlur(float value)
|
||||
{
|
||||
SetFloat(BlurAmountId, value);
|
||||
if (EnsureMaterial() && material.HasProperty(BlurSizeId))
|
||||
{
|
||||
material.SetFloat(BlurSizeId, value > 0.01f ? activeBlurSize : 0f);
|
||||
}
|
||||
}
|
||||
|
||||
public Tween TweenBlur(float value, float duration)
|
||||
{
|
||||
return TweenFloat(BlurAmountId, value, duration);
|
||||
}
|
||||
|
||||
public void SetWrongColor(float value)
|
||||
{
|
||||
SetFloat(WrongColorAmountId, value);
|
||||
}
|
||||
|
||||
public Tween TweenWrongColor(float value, float duration)
|
||||
{
|
||||
return TweenFloat(WrongColorAmountId, value, duration);
|
||||
}
|
||||
|
||||
public Tween PulseDistortion(float amount, float duration)
|
||||
{
|
||||
if (!EnsureMaterial())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return material.DOFloat(amount, DistortAmountId, Mathf.Max(0.01f, duration * 0.5f))
|
||||
.SetEase(Ease.InOutSine)
|
||||
.SetLoops(2, LoopType.Yoyo);
|
||||
}
|
||||
|
||||
public void SetImageAlpha(float alpha)
|
||||
{
|
||||
if (!driveImageLayer || imageSpriteRenderer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
imageSpriteRenderer.SetAlpha(alpha);
|
||||
}
|
||||
|
||||
public Tween TweenImageAlpha(float alpha, float duration)
|
||||
{
|
||||
if (!driveImageLayer || imageSpriteRenderer == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return imageSpriteRenderer.DOFade(alpha, duration);
|
||||
}
|
||||
|
||||
public void SetUfWeights(float ascii, float dream, float memory)
|
||||
{
|
||||
SetFloat(AsciiAmountId, ascii);
|
||||
SetFloat(DreamAmountId, dream);
|
||||
SetFloat(MemoryAmountId, memory);
|
||||
SetFloat(ScanlineAmountId, Mathf.Max(ascii, memory));
|
||||
}
|
||||
|
||||
public Tween TweenUfWeights(float ascii, float dream, float memory, float duration)
|
||||
{
|
||||
if (!EnsureMaterial())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Sequence sequence = DOTween.Sequence();
|
||||
sequence.Join(material.DOFloat(Mathf.Clamp01(ascii), AsciiAmountId, duration));
|
||||
sequence.Join(material.DOFloat(Mathf.Clamp01(dream), DreamAmountId, duration));
|
||||
sequence.Join(material.DOFloat(Mathf.Clamp01(memory), MemoryAmountId, duration));
|
||||
sequence.Join(material.DOFloat(Mathf.Clamp01(Mathf.Max(ascii, memory)), ScanlineAmountId, duration));
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public void SetSaturation(float saturation)
|
||||
{
|
||||
SetFloatRaw(HsvSaturationId, Mathf.Clamp(saturation, 0f, 2f));
|
||||
}
|
||||
|
||||
public Tween TweenSaturation(float saturation, float duration)
|
||||
{
|
||||
return TweenFloat(HsvSaturationId, Mathf.Clamp(saturation, 0f, 2f), duration);
|
||||
}
|
||||
|
||||
public Sequence StartGlitch(float duration = 1f)
|
||||
{
|
||||
if (!EnsureMaterial())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
duration = Mathf.Max(0.01f, duration);
|
||||
Sequence sequence = DOTween.Sequence();
|
||||
sequence.Join(material.DOFloat(1f, GlitchAmountId, duration));
|
||||
sequence.Join(material.DOFloat(0.02f, DistortAmountId, duration));
|
||||
sequence.Join(material.DOFloat(360f, HsvShiftId, duration).SetLoops(-1, LoopType.Yoyo));
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public void StopGlitch(float duration)
|
||||
{
|
||||
TweenFloat(GlitchAmountId, 0f, duration);
|
||||
TweenFloat(DistortAmountId, 0f, duration);
|
||||
TweenFloat(HsvShiftId, 0f, duration);
|
||||
}
|
||||
|
||||
public Tween TweenRoundWave(float value, float duration)
|
||||
{
|
||||
return TweenFloat(RoundWaveStrengthId, value, duration);
|
||||
}
|
||||
|
||||
private Tween TweenFloat(int propertyId, float value, float duration)
|
||||
{
|
||||
if (!EnsureMaterial() || !material.HasProperty(propertyId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return material.DOFloat(value, propertyId, duration);
|
||||
}
|
||||
|
||||
private void SetFloat(int propertyId, float value)
|
||||
{
|
||||
if (!EnsureMaterial() || !material.HasProperty(propertyId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
material.SetFloat(propertyId, Mathf.Clamp01(value));
|
||||
}
|
||||
|
||||
private void SetFloatRaw(int propertyId, float value)
|
||||
{
|
||||
if (!EnsureMaterial() || !material.HasProperty(propertyId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
material.SetFloat(propertyId, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0c7e3c9e6a546b49887860b3f26cf91
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream
|
||||
{
|
||||
/// <summary>
|
||||
/// Central tuning for Peipei eye-module visuals. Edit on EyeManager (EyeSystem).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class EyeVisualSettings
|
||||
{
|
||||
[Header("Color Reveal")]
|
||||
[Tooltip("Unfocused / gray state (0 = gray, 1 = full color).")]
|
||||
[Range(0f, 1f)] public float colorRevealMin;
|
||||
|
||||
[Tooltip("Focused / imagined color state.")]
|
||||
[Range(0f, 1f)] public float colorRevealMax = 1f;
|
||||
|
||||
[Header("Transition Duration (seconds)")]
|
||||
public float imagineColorDuration = 1f;
|
||||
public float cannotImagineDuration = 1f;
|
||||
public float eyeDisorderDuration = 2f;
|
||||
public float canSeeColorDuration = 1f;
|
||||
public float targetSwitchDuration = 1f;
|
||||
|
||||
[Header("Blur")]
|
||||
[Tooltip("Blur when unfocused or module idle.")]
|
||||
[Range(0f, 1f)] public float idleBlurAmount = 1f;
|
||||
|
||||
[Tooltip("Blur when focused and sharp.")]
|
||||
[Range(0f, 1f)] public float focusedBlurAmount;
|
||||
|
||||
[Tooltip("Shader _BlurSize when blur is active.")]
|
||||
[Range(0f, 0.02f)] public float blurSize = 0.008f;
|
||||
|
||||
[Header("Color Sweep (shader)")]
|
||||
[Tooltip("Width of the directional color sweep during ColorIn/FadeOut.")]
|
||||
[Range(0.001f, 1f)] public float revealWidth = 0.18f;
|
||||
|
||||
[Tooltip("Sweep direction in radians (0 = left-to-right).")]
|
||||
[Range(0f, 6.28318f)] public float revealRotation;
|
||||
|
||||
[Range(0f, 1f)] public float revealNoise = 0.08f;
|
||||
|
||||
[Header("Distortion Pulse")]
|
||||
[Tooltip("Peak _DistortAmount during ColorIn / FadeOut.")]
|
||||
[Range(0f, 0.08f)] public float colorPulseDistortion = 0.035f;
|
||||
|
||||
[Header("Wrong Color (Eye Disorder)")]
|
||||
public Color wrongColor = new(1f, 0.16f, 0.08f, 1f);
|
||||
|
||||
[Header("HSV")]
|
||||
[Range(0f, 2f)] public float hsvSaturation = 1f;
|
||||
|
||||
[Header("Glitch / Memory Wave")]
|
||||
public float glitchInDuration = 1f;
|
||||
public float roundWaveInDuration = 2f;
|
||||
public float roundWaveOutDuration = 0.5f;
|
||||
public float glitchOutDuration = 0.5f;
|
||||
|
||||
public float GetDurationForState(EyeSystem.EyeColorState state) => state switch
|
||||
{
|
||||
EyeSystem.EyeColorState.CanImagineColor => imagineColorDuration,
|
||||
EyeSystem.EyeColorState.CannotImagineColor => cannotImagineDuration,
|
||||
EyeSystem.EyeColorState.EyeDisorder => eyeDisorderDuration,
|
||||
EyeSystem.EyeColorState.CanSeeColor => canSeeColorDuration,
|
||||
_ => imagineColorDuration
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2767162520353a0458684a571ce59532
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,179 +1,133 @@
|
||||
using AibisDream;
|
||||
|
||||
public interface IEyeStateEffect
|
||||
{
|
||||
float TransitionDuration { get; }
|
||||
void InitializeEffect(EyeTarget target, ViewCameraManager cameraManager);
|
||||
void InitializeEffect(EyeTarget target, EyeSystem eyeSystem);
|
||||
void CleanupEffect(EyeTarget target);
|
||||
void ApplyFocusedEffect(EyeTarget target);
|
||||
void ApplyUnfocusedEffect(EyeTarget target);
|
||||
void ApplyFocusedEffect(EyeTarget target, EyeSystem eyeSystem);
|
||||
void ApplyUnfocusedEffect(EyeTarget target, EyeSystem eyeSystem);
|
||||
}
|
||||
|
||||
public class CanImagineColorEffect : IEyeStateEffect
|
||||
{
|
||||
public float TransitionDuration => 1f;
|
||||
|
||||
public void InitializeEffect(EyeTarget target, ViewCameraManager cameraManager)
|
||||
public void InitializeEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.SetToNoWrongColor();
|
||||
target.SetToMaxBurnRadius();
|
||||
target.SetToMaxColorReveal();
|
||||
target.SetToMinBlur();
|
||||
if (target.targetTransform)
|
||||
{
|
||||
cameraManager.SetCameraPosition(target.targetTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraManager.SetCameraPosition(target.transform);
|
||||
}
|
||||
eyeSystem?.FocusOnTarget(target, 0f);
|
||||
}
|
||||
|
||||
public void CleanupEffect(EyeTarget target)
|
||||
{
|
||||
target.SetToMinBurnRadius();
|
||||
target.SetToMinColorReveal();
|
||||
target.SetToMaxBlur();
|
||||
// Add cleanup logic here
|
||||
}
|
||||
|
||||
public void ApplyFocusedEffect(EyeTarget target)
|
||||
public void ApplyFocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.ColorIn(TransitionDuration);
|
||||
target.ColorIn(eyeSystem.GetEffectTransitionDuration());
|
||||
}
|
||||
|
||||
public void ApplyUnfocusedEffect(EyeTarget target)
|
||||
public void ApplyUnfocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.FadeOut(TransitionDuration);
|
||||
target.FadeOut(eyeSystem.GetEffectTransitionDuration());
|
||||
}
|
||||
}
|
||||
|
||||
public class CannotImagineColorEffect : IEyeStateEffect
|
||||
{
|
||||
public float TransitionDuration { get; } = 1f;
|
||||
|
||||
public void InitializeEffect(EyeTarget target, ViewCameraManager cameraManager)
|
||||
public void InitializeEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.SetToMinBlur(false);
|
||||
target.SetToMinBurnRadius();
|
||||
target.SetToMinBlur();
|
||||
target.SetToMinColorReveal();
|
||||
target.SetToNoWrongColor();
|
||||
if (target.targetTransform)
|
||||
{
|
||||
cameraManager.SetCameraPosition(target.targetTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraManager.SetCameraPosition(target.transform);
|
||||
}
|
||||
eyeSystem?.FocusOnTarget(target, 0f);
|
||||
}
|
||||
|
||||
public void CleanupEffect(EyeTarget target)
|
||||
{
|
||||
// Add cleanup logic here
|
||||
target.SetToMaxBlur(false);
|
||||
target.SetToMaxBlur();
|
||||
}
|
||||
|
||||
public void ApplyFocusedEffect(EyeTarget target)
|
||||
public void ApplyFocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.BlurOut(TransitionDuration, false);
|
||||
target.BlurOut(eyeSystem.GetEffectTransitionDuration());
|
||||
}
|
||||
|
||||
public void ApplyUnfocusedEffect(EyeTarget target)
|
||||
public void ApplyUnfocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.BlurIn(TransitionDuration, false);
|
||||
target.BlurIn(eyeSystem.GetEffectTransitionDuration());
|
||||
}
|
||||
}
|
||||
|
||||
public class EyeDisorderEffect : IEyeStateEffect
|
||||
{
|
||||
public float TransitionDuration { get; } = 2f;
|
||||
|
||||
public void InitializeEffect(EyeTarget target, ViewCameraManager cameraManager)
|
||||
public void InitializeEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.SetToMinBurnRadius();
|
||||
// Add initialization logic here
|
||||
if (target.targetTransform)
|
||||
{
|
||||
cameraManager.SetCameraPosition(target.targetTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraManager.SetCameraPosition(target.transform);
|
||||
}
|
||||
|
||||
target.SetToMinColorReveal();
|
||||
eyeSystem?.FocusOnTarget(target, 0f);
|
||||
target.SetToWrongColor();
|
||||
target.SetToMinBlur(false);
|
||||
}
|
||||
|
||||
public void CleanupEffect(EyeTarget target)
|
||||
{
|
||||
// Add cleanup logic here
|
||||
target.SetToNoWrongColor();
|
||||
}
|
||||
|
||||
public void ApplyFocusedEffect(EyeTarget target)
|
||||
{
|
||||
target.WrongColorIn(TransitionDuration);
|
||||
}
|
||||
|
||||
public void ApplyUnfocusedEffect(EyeTarget target)
|
||||
{
|
||||
target.WrongColorOut(TransitionDuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class CanSeeColorEffect : IEyeStateEffect
|
||||
{
|
||||
public float TransitionDuration { get; } = 1f;
|
||||
|
||||
public void InitializeEffect(EyeTarget target, ViewCameraManager cameraManager)
|
||||
{
|
||||
target.SetToNoWrongColor();
|
||||
target.SetToMaxBurnRadius();
|
||||
if (target.targetTransform)
|
||||
{
|
||||
cameraManager.SetCameraPosition(target.targetTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraManager.SetCameraPosition(target.transform);
|
||||
}
|
||||
|
||||
target.SetToMinBlur();
|
||||
}
|
||||
|
||||
public void CleanupEffect(EyeTarget target)
|
||||
{
|
||||
// Add cleanup logic here
|
||||
target.SetToNoWrongColor();
|
||||
}
|
||||
|
||||
public void ApplyFocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.WrongColorIn(eyeSystem.GetEffectTransitionDuration());
|
||||
}
|
||||
|
||||
public void ApplyUnfocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.WrongColorOut(eyeSystem.GetEffectTransitionDuration());
|
||||
}
|
||||
}
|
||||
|
||||
public class CanSeeColorEffect : IEyeStateEffect
|
||||
{
|
||||
public void InitializeEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.SetToNoWrongColor();
|
||||
target.SetToMaxColorReveal();
|
||||
eyeSystem?.FocusOnTarget(target, 0f);
|
||||
target.SetToMinBlur();
|
||||
}
|
||||
|
||||
public void CleanupEffect(EyeTarget target)
|
||||
{
|
||||
target.SetToMaxBlur();
|
||||
}
|
||||
|
||||
public void ApplyFocusedEffect(EyeTarget target)
|
||||
public void ApplyFocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.BlurOut(TransitionDuration);
|
||||
target.BlurOut(eyeSystem.GetEffectTransitionDuration());
|
||||
}
|
||||
|
||||
public void ApplyUnfocusedEffect(EyeTarget target)
|
||||
public void ApplyUnfocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
target.BlurIn(TransitionDuration);
|
||||
target.BlurIn(eyeSystem.GetEffectTransitionDuration());
|
||||
}
|
||||
}
|
||||
|
||||
public class HaveChip : IEyeStateEffect
|
||||
{
|
||||
public float TransitionDuration { get; } = 1f;
|
||||
|
||||
public void InitializeEffect(EyeTarget target, ViewCameraManager cameraManager)
|
||||
public void InitializeEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
}
|
||||
|
||||
public void CleanupEffect(EyeTarget target)
|
||||
{
|
||||
// Add cleanup logic here
|
||||
}
|
||||
|
||||
public void ApplyFocusedEffect(EyeTarget target)
|
||||
public void ApplyFocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
}
|
||||
|
||||
public void ApplyUnfocusedEffect(EyeTarget target)
|
||||
public void ApplyUnfocusedEffect(EyeTarget target, EyeSystem eyeSystem)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user