Files
aibis-dream/Assets/Scripts/MiniGame/Peipei/UF/UFSystem.cs
T
bottlefishandCursor 6dbd6917f9 refactor(peipei): UF 效果改由后处理 Volume 驱动
将 UF 想象/记忆/Ascii 状态从 unified shader weight 迁移至 Volume weight  tween。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 16:14:22 +08:00

373 lines
10 KiB
C#

using System;
using System.Collections;
using UnityEngine;
using AibisDream;
using AibisDream.FixSystem;
using UnityEngine.Rendering;
using Yarn.Unity;
using DG.Tweening;
using VolFx;
using AibisDream.Kit;
public class UFSystem : MonoBehaviour
{
private GameObject _UFCover;
private GameObject _UAudioule;
private EyeSystem eyeSystem;
public GameObject UFPanel;
public SpriteRenderer face;
private bool isLoopImage;
[Header("Global UF Cover")]
[SerializeField] private Volume FullAscillVolume;
[Header("Target Post-Processing Volumes")]
[SerializeField] private Volume imageAscillVolume;
[SerializeField] private Volume imageVolume;
[SerializeField] private Volume finalVolume;
private AsciiVol ascii;
private Tween scaleTween;
public enum UFState
{
UF,
imagination,
memory
}
private void Awake()
{
FixSystemCenter.SystemDic.Register(this);
eyeSystem = FindObjectOfType<EyeSystem>();
ClearUnifiedUfSpriteWeights();
}
public void TweenWeight(Volume postProcessingVolume, float targetWeight, float duration)
{
if (postProcessingVolume == null)
{
return;
}
DOTween.To(() => postProcessingVolume.weight, x => postProcessingVolume.weight = x, targetWeight, duration);
}
private void ClearUnifiedUfSpriteWeights()
{
eyeSystem?.SetUnifiedUfWeights(0f, 0f, 0f);
}
[YarnCommand("UF_spriteIn")]
public IEnumerator UF_spriteIn(float duration = 1.5f)
{
if (eyeSystem.CurrentTarget != null)
{
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
eyeSystem.CurrentTarget.ImageIn(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_spriteOut")]
public IEnumerator UF_spriteOut(float duration = 1.5f)
{
if (eyeSystem.CurrentTarget != null)
{
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
eyeSystem.CurrentTarget.ImageOut(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_AllspriteIn")]
public IEnumerator UF_AllspriteIn(float duration = 1.5f)
{
foreach (EyeTarget target in eyeSystem.Targets)
{
target.ImageIn(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_AllspriteOut")]
public IEnumerator UF_AllspriteOut(float duration = 1.5f)
{
foreach (EyeTarget target in eyeSystem.Targets)
{
target.ImageOut(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_faceIn")]
public IEnumerator UF_faceIn(float duration = 1.5f)
{
face.gameObject.SetActive(true);
face.DOFade(1f, duration);
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_faceOut")]
public IEnumerator UF_faceOut(float duration = 1.5f)
{
face.DOFade(0f, duration);
yield return new WaitForSeconds(duration);
face.gameObject.SetActive(false);
}
[YarnCommand("UF_ImaginationEffectIn")]
public IEnumerator UF_ImaginationEffectIn(float duration = 1.5f)
{
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
ClearUnifiedUfSpriteWeights();
TweenWeight(imageVolume, 1f, duration);
yield return new WaitForSeconds(0f);
}
[YarnCommand("UF_ImaginationEffectOut")]
public IEnumerator UF_ImaginationEffectOut(float duration = 1.5f)
{
TweenWeight(imageVolume, 0f, duration);
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
yield return new WaitForSeconds(0f);
}
[YarnCommand("UF_MemoryEffectIn")]
public IEnumerator UF_MemoryEffectIn(float duration = 1.5f)
{
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
ClearUnifiedUfSpriteWeights();
TweenWeight(finalVolume, 1f, duration);
yield return new WaitForSeconds(0f);
}
[YarnCommand("UF_MemoryEffectOut")]
public IEnumerator UF_MemoryEffectOut(float duration = 1.5f)
{
TweenWeight(finalVolume, 0f, duration);
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
yield return new WaitForSeconds(0f);
}
[YarnCommand("UF_EyeTargetAscillIn")]
public IEnumerator UF_EyeTargetAscillIn(float duration = 1.5f)
{
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
ClearUnifiedUfSpriteWeights();
TweenWeight(imageAscillVolume, 1f, duration);
yield return new WaitForSeconds(0f);
}
[YarnCommand("UF_EyeTargetAscillOut")]
public IEnumerator UF_EyeTargetAscillOut(float duration = 1.5f)
{
TweenWeight(imageAscillVolume, 0f, duration);
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
yield return new WaitForSeconds(0f);
}
[YarnCommand("UF_SetBorkenValue")]
public void UF_Borken(int value)
{
if (FullAscillVolume == null)
{
return;
}
if (!FullAscillVolume.gameObject.activeInHierarchy)
{
FullAscillVolume.gameObject.SetActive(true);
}
if (FullAscillVolume.profile.TryGet(out ascii))
{
ascii.m_Depth.value = value;
ascii.m_Ascii.value = Color.red;
}
}
[YarnCommand("StartUFEffect_loop")]
public void UFImageLoop()
{
StartCoroutine(UFImageLoopProcess());
}
[YarnCommand("StopUFEffect_loop")]
public void StopUFImageLoop()
{
isLoopImage = false;
}
[YarnCommand("UF_fightEffect")]
public void UF_fightEffect()
{
ClearUnifiedUfSpriteWeights();
scaleTween = DOTween.To(() => 0f, t =>
{
if (imageVolume != null)
{
imageVolume.weight = Mathf.Lerp(0f, 1f, t);
}
if (imageAscillVolume != null)
{
imageAscillVolume.weight = Mathf.Lerp(0f, 1f, t);
}
if (finalVolume != null)
{
finalVolume.weight = Mathf.Lerp(1f, 0f, t);
}
}, 1f, 1f)
.SetEase(Ease.InOutSine)
.SetLoops(-1, LoopType.Yoyo);
}
[YarnCommand("UF_StopfightEffect")]
public void UF_StopfightEffect()
{
scaleTween?.Kill();
}
public IEnumerator UFImageLoopProcess()
{
int index = 0;
isLoopImage = true;
while (isLoopImage)
{
eyeSystem.StartCoroutine(eyeSystem.SetTargetCoroutine(eyeSystem.Targets[index].name, false));
yield return new WaitForSeconds(0.5f);
StartCoroutine(UF_spriteIn(0.5f));
StartCoroutine(UF_ImaginationEffectIn(0.5f));
eyeSystem.Targets[index].ImageIn(0.5f);
yield return new WaitForSeconds(0.5f);
StartCoroutine(UF_ImaginationEffectOut(0.5f));
StartCoroutine(UF_MemoryEffectIn(0.5f));
yield return new WaitForSeconds(1f);
eyeSystem.Targets[index].ImageOut(0.5f);
StartCoroutine(UF_MemoryEffectOut(0.5f));
index++;
if (index >= eyeSystem.Targets.Count - 2)
{
index = 0;
}
}
}
public void OpenUFView()
{
ClearUnifiedUfSpriteWeights();
if (FullAscillVolume != null && !FullAscillVolume.gameObject.activeInHierarchy)
{
FullAscillVolume.gameObject.SetActive(true);
}
if (imageAscillVolume != null)
{
imageAscillVolume.weight = 1f;
}
if (imageVolume != null)
{
imageVolume.weight = 0f;
}
if (finalVolume != null)
{
finalVolume.weight = 0f;
}
}
public void CloseUFView()
{
if (FullAscillVolume != null && FullAscillVolume.gameObject.activeInHierarchy)
{
FullAscillVolume.gameObject.SetActive(false);
}
if (imageAscillVolume != null)
{
imageAscillVolume.weight = 1f;
}
if (imageVolume != null)
{
imageVolume.weight = 0f;
}
if (finalVolume != null)
{
finalVolume.weight = 0f;
}
ClearUnifiedUfSpriteWeights();
}
public void OpenCover()
{
var bodyModuleSystem = FixSystemCenter.SystemDic.Get<BodyModuleSystem>();
_UFCover = bodyModuleSystem.FindBodyModuleByName("UF").transform.Find("Cover").gameObject;
if (_UFCover.activeInHierarchy)
{
_UFCover.SetActive(false);
}
}
public void RemoveUF()
{
var bodyModuleSystem = FixSystemCenter.SystemDic.Get<BodyModuleSystem>();
_UAudioule = bodyModuleSystem.FindBodyModuleByName("UF").gameObject;
if (_UAudioule.activeInHierarchy)
{
_UAudioule.SetActive(false);
}
}
[YarnCommand("UF_SwitchState")]
public IEnumerator SwitchState(string stateName, float duration)
{
if (!Enum.TryParse(stateName, true, out UFState state))
{
Debug.LogError($"Invalid state name: {stateName}");
yield break;
}
AudioManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
ClearUnifiedUfSpriteWeights();
switch (state)
{
case UFState.UF:
TweenWeight(imageAscillVolume, 1f, duration);
TweenWeight(imageVolume, 0f, duration);
TweenWeight(finalVolume, 0f, duration);
break;
case UFState.imagination:
TweenWeight(imageAscillVolume, 0f, duration);
TweenWeight(imageVolume, 1f, duration);
TweenWeight(finalVolume, 0f, duration);
break;
case UFState.memory:
TweenWeight(imageAscillVolume, 0f, duration);
TweenWeight(imageVolume, 0f, duration);
TweenWeight(finalVolume, 1f, duration);
break;
default:
Debug.LogError($"Unhandled state: {state}");
yield break;
}
yield return new WaitForSeconds(duration);
}
}