fade in 时启用 overlay GameObject,fade out 完成后隐藏。 Co-authored-by: Cursor <cursoragent@cursor.com>
341 lines
11 KiB
C#
341 lines
11 KiB
C#
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 = Application.isPlaying
|
|
? spriteRenderer.material
|
|
: spriteRenderer.sharedMaterial;
|
|
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;
|
|
}
|
|
|
|
alpha = Mathf.Clamp01(alpha);
|
|
if (alpha > 0f)
|
|
{
|
|
imageSpriteRenderer.gameObject.SetActive(true);
|
|
imageSpriteRenderer.enabled = true;
|
|
}
|
|
|
|
imageSpriteRenderer.SetAlpha(alpha);
|
|
|
|
if (alpha <= 0f)
|
|
{
|
|
imageSpriteRenderer.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
public Tween TweenImageAlpha(float alpha, float duration)
|
|
{
|
|
if (!driveImageLayer || imageSpriteRenderer == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
alpha = Mathf.Clamp01(alpha);
|
|
if (alpha > 0f)
|
|
{
|
|
imageSpriteRenderer.gameObject.SetActive(true);
|
|
imageSpriteRenderer.enabled = true;
|
|
}
|
|
|
|
return imageSpriteRenderer.DOFade(alpha, duration)
|
|
.OnComplete(() =>
|
|
{
|
|
if (alpha <= 0f && imageSpriteRenderer != null)
|
|
{
|
|
imageSpriteRenderer.gameObject.SetActive(false);
|
|
}
|
|
});
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|