328 lines
8.9 KiB
C#
328 lines
8.9 KiB
C#
using AibisDream;
|
||
using AibisDream.Kit;
|
||
using AibisDream.Utility;
|
||
using DG.Tweening;
|
||
using UnityEngine;
|
||
|
||
public class EyeTarget : MonoBehaviour
|
||
{
|
||
public Transform targetTransform;
|
||
|
||
[Header("Optional overlay sprite for UF imagination")]
|
||
[SerializeField] private SpriteRenderer imageSpriteRender;
|
||
|
||
[SerializeField] private Shader unifiedSpriteShader;
|
||
[SerializeField] private EyeTargetVisual unifiedVisual;
|
||
|
||
public Color _color;
|
||
|
||
private EyeVisualSettings visualSettings = new();
|
||
|
||
private void Awake()
|
||
{
|
||
var spriteRenderer = GetComponent<SpriteRenderer>();
|
||
if (spriteRenderer == null)
|
||
{
|
||
Debug.LogError($"[EyeTarget] {name} 缺少 SpriteRenderer。", this);
|
||
return;
|
||
}
|
||
|
||
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()
|
||
{
|
||
SetToMinColorReveal();
|
||
SetToMaxBlur();
|
||
SetToNoWrongColor();
|
||
SetNoImage();
|
||
}
|
||
|
||
public void ImageIn(float duration)
|
||
{
|
||
unifiedVisual?.TweenImageAlpha(1f, duration);
|
||
}
|
||
|
||
public void ImageOut(float duration)
|
||
{
|
||
unifiedVisual?.TweenImageAlpha(0f, duration);
|
||
}
|
||
|
||
public void SetNoImage()
|
||
{
|
||
unifiedVisual?.SetImageAlpha(0f);
|
||
}
|
||
|
||
public void SetToMinColorReveal()
|
||
{
|
||
unifiedVisual?.SetColorReveal(visualSettings.colorRevealMin);
|
||
}
|
||
|
||
public void SetToMaxColorReveal()
|
||
{
|
||
unifiedVisual?.SetColorReveal(visualSettings.colorRevealMax);
|
||
}
|
||
|
||
public void SetToMaxBlur()
|
||
{
|
||
unifiedVisual?.SetBlur(visualSettings.idleBlurAmount);
|
||
}
|
||
|
||
public void SetToMinBlur()
|
||
{
|
||
unifiedVisual?.SetBlur(visualSettings.focusedBlurAmount);
|
||
}
|
||
|
||
public void SetToNoWrongColor()
|
||
{
|
||
unifiedVisual?.SetWrongColor(0f);
|
||
}
|
||
|
||
public void SetToWrongColor()
|
||
{
|
||
unifiedVisual?.SetWrongColor(1f);
|
||
}
|
||
|
||
public void FadeOut(float duration)
|
||
{
|
||
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)
|
||
{
|
||
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)
|
||
{
|
||
unifiedVisual?.TweenWrongColor(1f, duration)?.SetEase(Ease.InOutSine);
|
||
}
|
||
|
||
public void WrongColorOut(float duration)
|
||
{
|
||
unifiedVisual?.TweenWrongColor(0f, duration)?.SetEase(Ease.InOutSine);
|
||
}
|
||
|
||
public void BlurIn(float duration)
|
||
{
|
||
AudioManager.Instance.PlaySfx("event:/ActionFB/visualturn");
|
||
var tween = unifiedVisual?.TweenBlur(visualSettings.idleBlurAmount, duration);
|
||
tween?.SetEase(Ease.InOutSine).OnComplete(StopVisualTurnSfx);
|
||
}
|
||
|
||
public void BlurOut(float duration)
|
||
{
|
||
AudioManager.Instance.PlaySfx("event:/ActionFB/visualturn");
|
||
var tween = unifiedVisual?.TweenBlur(visualSettings.focusedBlurAmount, duration);
|
||
tween?.SetEase(Ease.InOutSine).OnComplete(StopVisualTurnSfx);
|
||
}
|
||
|
||
public void ColorBack()
|
||
{
|
||
SetToMaxColorReveal();
|
||
SetToNoWrongColor();
|
||
SetToMinBlur();
|
||
}
|
||
|
||
public void ColorLost()
|
||
{
|
||
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 = Application.isPlaying
|
||
? spriteRenderer.material
|
||
: spriteRenderer.sharedMaterial;
|
||
|
||
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;
|
||
var runtimeMaterial = new Material(shader)
|
||
{
|
||
name = $"{gameObject.name}_EyeUnified_Runtime"
|
||
};
|
||
if (mainTex != null)
|
||
{
|
||
runtimeMaterial.SetTexture("_MainTex", mainTex);
|
||
}
|
||
|
||
if (Application.isPlaying)
|
||
{
|
||
spriteRenderer.material = runtimeMaterial;
|
||
}
|
||
else
|
||
{
|
||
spriteRenderer.sharedMaterial = runtimeMaterial;
|
||
}
|
||
}
|
||
|
||
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");
|
||
}
|
||
}
|