feat(fix-system): 支持记忆画面使用UI显示

This commit is contained in:
2026-06-29 22:57:14 +08:00
parent f42ec20dc8
commit 268bdd19d9
+94 -125
View File
@@ -1,5 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Yarn.Unity;
@@ -7,8 +6,8 @@ using AibisDream.Framework;
using AibisDream.Kit;
using UnityEngine.Rendering;
using UnityEngine.UI;
using AibisDream.Kit;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.Serialization;
namespace AibisDream.FixSystem
{
@@ -41,8 +40,15 @@ namespace AibisDream.FixSystem
[SerializeField] private GameObject memoryView;
[SerializeField] private GameObject projector;
[SerializeField] private SpriteRenderer memoryFinishedSpriteRenderer; // 用于显示记忆处理结束的表现
[SerializeField] private SpriteRenderer memoryFinishedImageNoColor; // 用于显示记忆处理结束的表现
[SerializeField] private Image memoryFinishedImage; // UI彩色记忆层
[SerializeField] private Image memoryFinishedNoColorImage; // UI去色记忆层
[FormerlySerializedAs("memoryFinishedspRender")]
[FormerlySerializedAs("memoryFinishedSpriteRenderer")]
[HideInInspector]
[SerializeField] private SpriteRenderer legacyMemoryFinishedSpriteRenderer;
[FormerlySerializedAs("memoryFinishedImageNoColor")]
[HideInInspector]
[SerializeField] private SpriteRenderer legacyMemoryFinishedImageNoColor;
[SerializeField] private Volume mainEffect;
[SerializeField] private Volume memoryClarityVolume;
@@ -66,14 +72,11 @@ namespace AibisDream.FixSystem
[SerializeField] private Material fadeMaterial;
private Material runtimeMemoryMaterial;
private Material runtimeNoColorMemoryMaterial;
private readonly List<RenderTexture> runtimeRenderTextures = new();
public void OpenMemoryView()
{
memoryGroup.SetActive(true);
memoryView.gameObject.SetActive(true);
EnsureMemoryRenderTargets();
StartCoroutine(PrimeMemoryRenderTargets());
}
public IEnumerator DropMemoryProjector()
@@ -161,6 +164,7 @@ namespace AibisDream.FixSystem
private void InitSystem()
{
FixSystemCenter.SystemDic.Register(this);
DisableLegacyRenderTextureCameras();
if (memoryGroup != null)
memoryGroup.SetActive(false);
}
@@ -180,113 +184,18 @@ namespace AibisDream.FixSystem
Destroy(runtimeMemoryMaterial);
if (runtimeNoColorMemoryMaterial != null)
Destroy(runtimeNoColorMemoryMaterial);
foreach (var renderTexture in runtimeRenderTextures)
{
if (renderTexture == null)
continue;
renderTexture.Release();
Destroy(renderTexture);
}
runtimeRenderTextures.Clear();
}
private void EnsureMemoryRenderTargets()
private void DisableLegacyRenderTextureCameras()
{
if (memoryGroup == null || memoryView == null)
if (memoryGroup == null)
return;
var cameras = memoryGroup.GetComponentsInChildren<Camera>(true);
foreach (var renderCamera in cameras)
{
if (renderCamera == null || renderCamera.targetTexture == null)
continue;
renderCamera.allowHDR = false;
renderCamera.allowMSAA = false;
var originalTexture = renderCamera.targetTexture;
var targetTexture = originalTexture;
if (ShouldReplaceRenderTexture(originalTexture))
{
targetTexture = CreateCompatibleRenderTexture(originalTexture);
renderCamera.targetTexture = targetTexture;
RebindMemoryRawImages(originalTexture, targetTexture);
}
if (!targetTexture.IsCreated())
{
targetTexture.Create();
}
}
}
private static bool ShouldReplaceRenderTexture(RenderTexture renderTexture)
{
if (renderTexture == null)
return true;
if (!SystemInfo.SupportsRenderTextureFormat(renderTexture.format))
return true;
var maxSize = Mathf.Min(SystemInfo.maxTextureSize, 2048);
return renderTexture.width > maxSize || renderTexture.height > maxSize;
}
private RenderTexture CreateCompatibleRenderTexture(RenderTexture source)
{
var maxSize = Mathf.Min(SystemInfo.maxTextureSize, 2048);
var sourceWidth = source != null ? source.width : Screen.width;
var sourceHeight = source != null ? source.height : Screen.height;
var scale = Mathf.Min(1f, maxSize / (float)Mathf.Max(sourceWidth, sourceHeight));
var width = Mathf.Max(1, Mathf.RoundToInt(sourceWidth * scale));
var height = Mathf.Max(1, Mathf.RoundToInt(sourceHeight * scale));
var renderTexture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32)
{
name = source != null ? $"{source.name}_RuntimeCompatible" : "Memory_RuntimeCompatible",
antiAliasing = 1,
useMipMap = false,
autoGenerateMips = false
};
renderTexture.Create();
runtimeRenderTextures.Add(renderTexture);
return renderTexture;
}
private void RebindMemoryRawImages(Texture oldTexture, Texture newTexture)
{
var rawImages = memoryView.GetComponentsInChildren<RawImage>(true);
foreach (var rawImage in rawImages)
{
if (rawImage != null && rawImage.texture == oldTexture)
{
rawImage.texture = newTexture;
}
}
}
private IEnumerator PrimeMemoryRenderTargets()
{
yield return null;
ForceRenderMemoryTargets();
yield return new WaitForEndOfFrame();
ForceRenderMemoryTargets();
}
private void ForceRenderMemoryTargets()
{
if (memoryGroup == null || !memoryGroup.activeInHierarchy)
return;
var cameras = memoryGroup.GetComponentsInChildren<Camera>(true);
foreach (var renderCamera in cameras)
{
if (renderCamera != null && renderCamera.enabled && renderCamera.targetTexture != null)
{
renderCamera.Render();
}
if (renderCamera != null && renderCamera.targetTexture != null)
renderCamera.enabled = false;
}
}
@@ -391,7 +300,7 @@ namespace AibisDream.FixSystem
if (fadeMaterial != null)
SetFloatIfExists(DirectionalDistortionFadeId, FadeMaterialStartValue);
ResetSpriteTuning();
memoryFinishedSpriteRenderer.color = Color.black;
SetMemoryColor(Color.black);
SetVolumeWeight(memoryProcessVolume, 0f);
_activePunchTape = null;
@@ -434,7 +343,7 @@ namespace AibisDream.FixSystem
[YarnCommand("PlayMemory")]
public IEnumerator PlayMemory(bool useYarn = false, string memName = "")
{
memoryFinishedSpriteRenderer.color = Color.white;
SetMemoryColor(Color.white);
PunchTapeManager.Instance.CloseFavoritesPanel();
if (useYarn)
@@ -445,8 +354,7 @@ namespace AibisDream.FixSystem
var memoryHandle = ResourceSystem.LoadAsync<Sprite>(memoryKey);
yield return memoryHandle;
Sprite memSprite = memoryHandle.Status == AsyncOperationStatus.Succeeded ? memoryHandle.Result : null;
memoryFinishedSpriteRenderer.sprite = memSprite;
memoryFinishedImageNoColor.sprite = memSprite;
SetMemorySprite(memSprite);
if (memSprite == null)
{
Debug.LogError("Memory not found: " + memoryKey);
@@ -506,8 +414,7 @@ namespace AibisDream.FixSystem
Sprite memorySprite = searchMemoryHandle.Status == AsyncOperationStatus.Succeeded
? searchMemoryHandle.Result
: null;
memoryFinishedSpriteRenderer.sprite = memorySprite;
memoryFinishedImageNoColor.sprite = memorySprite;
SetMemorySprite(memorySprite);
if (memorySprite == null)
{
Debug.LogError("Memory not found: " + searchMemoryKey);
@@ -519,7 +426,7 @@ namespace AibisDream.FixSystem
yield return new WaitForSeconds(SearchStartDelay);
AudioManager.Instance.SetSfxParam("event:/Amb/amb_mem_tuning", "is_mem_tuning", 1);
memoryFinishedSpriteRenderer.color = Color.white;
SetMemoryColor(Color.white);
SetVolumeWeight(memoryProcessVolume, 0f);
isProcessing = true;
frequencySlider.PrepareForSearch();
@@ -600,10 +507,14 @@ namespace AibisDream.FixSystem
private void PrepareRuntimeMemoryMaterial()
{
if (!useSpriteShaderTuning || memoryFinishedSpriteRenderer == null || fadeMaterial == null)
if (!useSpriteShaderTuning || !HasMemoryGraphic())
return;
var shader = fadeMaterial.shader;
var baseMaterial = GetColorMemoryMaterial();
if (baseMaterial == null)
baseMaterial = fadeMaterial;
var shader = baseMaterial != null ? baseMaterial.shader : null;
if (shader == null || shader.name != "AibisDream/MemoryTuningSprite")
shader = Shader.Find("AibisDream/MemoryTuningSprite");
if (shader == null)
@@ -612,19 +523,20 @@ namespace AibisDream.FixSystem
return;
}
runtimeMemoryMaterial = CreateRuntimeMemoryMaterial(fadeMaterial, shader, "Color", 0f, 1f);
memoryFinishedSpriteRenderer.sharedMaterial = runtimeMemoryMaterial;
runtimeMemoryMaterial = CreateRuntimeMemoryMaterial(baseMaterial, shader, "Color", 0f, 1f);
SetColorMemoryMaterial(runtimeMemoryMaterial);
fadeMaterial = runtimeMemoryMaterial;
if (memoryFinishedImageNoColor != null && memoryFinishedImageNoColor.sharedMaterial != null)
var noColorBaseMaterial = GetNoColorMemoryMaterial();
if (noColorBaseMaterial != null)
{
runtimeNoColorMemoryMaterial = CreateRuntimeMemoryMaterial(
memoryFinishedImageNoColor.sharedMaterial,
noColorBaseMaterial,
shader,
"NoColor",
1f,
1.8f);
memoryFinishedImageNoColor.sharedMaterial = runtimeNoColorMemoryMaterial;
SetNoColorMemoryMaterial(runtimeNoColorMemoryMaterial);
}
ResetSpriteTuning();
@@ -637,16 +549,73 @@ namespace AibisDream.FixSystem
float grayscale,
float contrast)
{
var material = new Material(source)
{
shader = shader,
name = $"{source.name}_RuntimeMemoryTuning_{suffix}"
};
var material = source != null ? new Material(source) : new Material(shader);
material.shader = shader;
material.name = $"{(source != null ? source.name : shader.name)}_RuntimeMemoryTuning_{suffix}";
SetFloatIfExists(material, MemoryGrayscaleId, grayscale);
SetFloatIfExists(material, MemoryContrastId, contrast);
return material;
}
private bool HasMemoryGraphic()
{
return memoryFinishedImage != null || legacyMemoryFinishedSpriteRenderer != null;
}
private void SetMemorySprite(Sprite sprite)
{
if (memoryFinishedImage != null)
memoryFinishedImage.sprite = sprite;
if (memoryFinishedNoColorImage != null)
memoryFinishedNoColorImage.sprite = sprite;
if (legacyMemoryFinishedSpriteRenderer != null)
legacyMemoryFinishedSpriteRenderer.sprite = sprite;
if (legacyMemoryFinishedImageNoColor != null)
legacyMemoryFinishedImageNoColor.sprite = sprite;
}
private void SetMemoryColor(Color color)
{
if (memoryFinishedImage != null)
memoryFinishedImage.color = color;
if (legacyMemoryFinishedSpriteRenderer != null)
legacyMemoryFinishedSpriteRenderer.color = color;
}
private Material GetColorMemoryMaterial()
{
if (memoryFinishedImage != null)
return memoryFinishedImage.material;
return legacyMemoryFinishedSpriteRenderer != null
? legacyMemoryFinishedSpriteRenderer.sharedMaterial
: null;
}
private Material GetNoColorMemoryMaterial()
{
if (memoryFinishedNoColorImage != null)
return memoryFinishedNoColorImage.material;
return legacyMemoryFinishedImageNoColor != null
? legacyMemoryFinishedImageNoColor.sharedMaterial
: null;
}
private void SetColorMemoryMaterial(Material material)
{
if (memoryFinishedImage != null)
memoryFinishedImage.material = material;
if (legacyMemoryFinishedSpriteRenderer != null)
legacyMemoryFinishedSpriteRenderer.sharedMaterial = material;
}
private void SetNoColorMemoryMaterial(Material material)
{
if (memoryFinishedNoColorImage != null)
memoryFinishedNoColorImage.material = material;
if (legacyMemoryFinishedImageNoColor != null)
legacyMemoryFinishedImageNoColor.sharedMaterial = material;
}
public bool IsProcessing()
{