using DG.Tweening; using UnityEngine; using AibisDream.Utility; namespace AibisDream { /// /// Drives the unified EyeUnifiedSprite path for Peipei eye targets. /// 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(); } 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); } } }