Files

440 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 float PresentationSpeed => eyeSystem != null ? eyeSystem.PresentationSpeed : 1f;
private float ScaleDuration(float duration) =>
eyeSystem != null ? eyeSystem.ScaleDuration(duration) : duration;
private void PlayPresentationSfx(string eventName)
{
AudioManager.Instance.PlaySfx(eventName, pitch: PresentationSpeed);
}
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);
}
private EyeTarget ResolveSpriteTarget()
{
if (eyeSystem == null)
{
return null;
}
if (eyeSystem.CurrentTarget != null)
{
return eyeSystem.CurrentTarget;
}
if (YarnVariableStorage.Instance != null
&& YarnVariableStorage.Instance.TryGetValue("$currentEyeTarget", out string targetName)
&& !string.IsNullOrEmpty(targetName))
{
return eyeSystem.FindEyeTargetByName(targetName);
}
return null;
}
[YarnCommand("UF_spriteIn")]
public IEnumerator UF_spriteIn(float duration = 1.5f)
{
duration = ScaleDuration(duration);
var target = ResolveSpriteTarget();
if (target != null)
{
PlayPresentationSfx("event:/ActionFB/color_imagine");
target.ImageIn(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_spriteOut")]
public IEnumerator UF_spriteOut(float duration = 1.5f)
{
duration = ScaleDuration(duration);
var target = ResolveSpriteTarget();
if (target != null)
{
PlayPresentationSfx("event:/ActionFB/color_imagine");
target.ImageOut(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_AllspriteIn")]
public IEnumerator UF_AllspriteIn(float duration = 1.5f)
{
duration = ScaleDuration(duration);
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)
{
duration = ScaleDuration(duration);
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)
{
if (face == null)
{
Debug.LogWarning("[UFSystem] UF_faceIn: face SpriteRenderer 未绑定。", this);
yield break;
}
if (face.sprite == null)
{
Debug.LogWarning("[UFSystem] UF_faceIn: face.sprite 为空(可能是 aseprite 重导入后子资源 ID 失效)。", this);
}
duration = ScaleDuration(duration);
face.gameObject.SetActive(true);
face.DOFade(1f, duration);
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_faceOut")]
public IEnumerator UF_faceOut(float duration = 1.5f)
{
if (face == null)
{
yield break;
}
duration = ScaleDuration(duration);
face.DOFade(0f, duration);
yield return new WaitForSeconds(duration);
face.gameObject.SetActive(false);
}
[YarnCommand("UF_ImaginationEffectIn")]
public IEnumerator UF_ImaginationEffectIn(float duration = 1.5f)
{
duration = ScaleDuration(duration);
PlayPresentationSfx("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)
{
duration = ScaleDuration(duration);
TweenWeight(imageVolume, 0f, duration);
PlayPresentationSfx("event:/ActionFB/color_imagine");
yield return new WaitForSeconds(0f);
}
[YarnCommand("UF_MemoryEffectIn")]
public IEnumerator UF_MemoryEffectIn(float duration = 1.5f)
{
duration = ScaleDuration(duration);
PlayPresentationSfx("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)
{
duration = ScaleDuration(duration);
TweenWeight(finalVolume, 0f, duration);
PlayPresentationSfx("event:/ActionFB/color_imagine");
yield return new WaitForSeconds(0f);
}
[YarnCommand("UF_EyeTargetAscillIn")]
public IEnumerator UF_EyeTargetAscillIn(float duration = 1.5f)
{
duration = ScaleDuration(duration);
PlayPresentationSfx("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)
{
duration = ScaleDuration(duration);
TweenWeight(imageAscillVolume, 0f, duration);
PlayPresentationSfx("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();
float loopDuration = ScaleDuration(1f);
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, loopDuration)
.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(ScaleDuration(0.5f));
StartCoroutine(UF_spriteIn(0.5f));
StartCoroutine(UF_ImaginationEffectIn(0.5f));
eyeSystem.Targets[index].ImageIn(ScaleDuration(0.5f));
yield return new WaitForSeconds(ScaleDuration(0.5f));
StartCoroutine(UF_ImaginationEffectOut(0.5f));
StartCoroutine(UF_MemoryEffectIn(0.5f));
yield return new WaitForSeconds(ScaleDuration(1f));
eyeSystem.Targets[index].ImageOut(ScaleDuration(0.5f));
StartCoroutine(UF_MemoryEffectOut(0.5f));
index++;
if (index >= eyeSystem.Targets.Count - 2)
{
index = 0;
}
}
}
public void OpenUFView()
{
ClearUnifiedUfSpriteWeights();
// 先于 EyeSystem.OnEnterUF 段 SwitchState / sprite 极密,禁止 autoBlink 与过渡眨眼
eyeSystem?.SetNonExplicitBlinkSuppressed(true);
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();
eyeSystem?.SetNonExplicitBlinkSuppressed(false);
}
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;
}
duration = ScaleDuration(duration);
PlayPresentationSfx("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);
}
}