feat(frameAnima): 动画系统前四个阶段

This commit is contained in:
2026-07-15 15:13:56 +08:00
parent 19b6b9c4e2
commit 85a3fc9e14
108 changed files with 15448 additions and 35 deletions
+160 -25
View File
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using Shapes;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
#if UNITY_EDITOR
using UnityEditor;
#endif
@@ -132,6 +133,9 @@ namespace AibisDream.UI
private bool _cursorVisible = true;
private Coroutine _crashSpamCoroutine;
private double _editorLastRepaintTime;
#if UNITY_EDITOR
private GUIStyle _editorPreviewLabelStyle;
#endif
// 全局 alpha(用于 DreamDoorSystem 淡入淡出)
public float Alpha { get; set; } = 0f;
@@ -155,12 +159,6 @@ namespace AibisDream.UI
private void Update()
{
if (!Application.isPlaying)
{
EditorUpdate();
return;
}
if (_phase == TerminalPhase.WaitingInput)
HandleTypingInput();
else if (_phase == TerminalPhase.Confirming)
@@ -169,6 +167,17 @@ namespace AibisDream.UI
public override void OnDisable()
{
#if UNITY_EDITOR
SceneView.duringSceneGui -= OnEditorSceneGui;
EditorApplication.update -= EditorPreviewUpdate;
if (!Application.isPlaying)
{
DrawCommand.ClearAllCommands();
_phase = TerminalPhase.Idle;
StopAllCoroutines();
return;
}
#endif
base.OnDisable();
_phase = TerminalPhase.Idle;
StopAllCoroutines();
@@ -176,11 +185,20 @@ namespace AibisDream.UI
public override void OnEnable()
{
base.OnEnable();
EnsureDefaultFontReference();
#if UNITY_EDITOR
if (!Application.isPlaying)
{
SceneView.duringSceneGui -= OnEditorSceneGui;
SceneView.duringSceneGui += OnEditorSceneGui;
EditorApplication.update -= EditorPreviewUpdate;
EditorApplication.update += EditorPreviewUpdate;
EditorApply();
return;
}
#endif
base.OnEnable();
}
private void OnValidate()
@@ -188,8 +206,10 @@ namespace AibisDream.UI
EnsureDefaultFontReference();
MorphProgress = morphProgress;
#if UNITY_EDITOR
if (!Application.isPlaying)
EditorApply();
#endif
}
#endregion
@@ -265,6 +285,12 @@ namespace AibisDream.UI
public override void DrawShapes(Camera cam)
{
#if UNITY_EDITOR
// 编辑模式预览改走 SceneView HandlesURP 下 Shapes 文本池不会回收。
if (!Application.isPlaying)
return;
#endif
if (Alpha <= 0.01f) return;
float frameProgress = Mathf.SmoothStep(0f, 1f, MorphProgress);
@@ -898,36 +924,144 @@ namespace AibisDream.UI
#endregion
private void EditorUpdate()
{
#if UNITY_EDITOR
UpdateEditorPreview();
#endif
}
private void EditorApply()
{
#if UNITY_EDITOR
ApplyEditorPreviewState();
if (previewInEditor)
SceneView.RepaintAll();
else
DrawCommand.ClearAllCommands();
#endif
}
#if UNITY_EDITOR
private void UpdateEditorPreview()
private void OnEditorSceneGui(SceneView sceneView)
{
ApplyEditorPreviewState();
if (Application.isPlaying || !previewInEditor || Alpha <= 0.01f)
return;
if (previewInEditor)
DrawEditorScenePreview();
}
private void DrawEditorScenePreview()
{
float frameProgress = Mathf.SmoothStep(0f, 1f, MorphProgress);
float textReveal = frameProgress >= 0.999f ? 1f : 0f;
Vector2 currentSize = Vector2.Lerp(morphStartSize, terminalSize, frameProgress);
Matrix4x4 previousMatrix = Handles.matrix;
Color previousColor = Handles.color;
CompareFunction previousZTest = Handles.zTest;
Handles.matrix = transform.localToWorldMatrix;
Handles.zTest = CompareFunction.Always;
Color bg = colBg;
bg.a *= Alpha;
Handles.DrawSolidRectangleWithOutline(
new Rect(-currentSize.x * 0.5f, -currentSize.y * 0.5f, currentSize.x, currentSize.y),
bg,
Color.clear);
float halfW = currentSize.x * 0.5f - padding * 0.48f;
float halfH = currentSize.y * 0.5f - padding * 0.42f;
Color border = colWhiteGlow;
border.a *= Alpha * 0.58f;
Handles.color = border;
Handles.DrawLine(new Vector3(-halfW, halfH, 0f), new Vector3(halfW, halfH, 0f));
Handles.DrawLine(new Vector3(-halfW, -halfH, 0f), new Vector3(halfW, -halfH, 0f));
Handles.DrawLine(new Vector3(-halfW, -halfH, 0f), new Vector3(-halfW, halfH, 0f));
Handles.DrawLine(new Vector3(halfW, -halfH, 0f), new Vector3(halfW, halfH, 0f));
if (textReveal <= 0f)
{
EditorApplication.QueuePlayerLoopUpdate();
double now = EditorApplication.timeSinceStartup;
if (now - _editorLastRepaintTime > 0.08d)
{
_editorLastRepaintTime = now;
SceneView.RepaintAll();
}
Handles.matrix = previousMatrix;
Handles.color = previousColor;
Handles.zTest = previousZTest;
return;
}
float contentHalfW = currentSize.x * 0.5f;
float contentHalfH = currentSize.y * 0.5f;
float titleY = contentHalfH - padding * 0.62f;
float separatorY = titleY - GetHeaderBandHeight(currentSize) * 0.48f;
DrawEditorLabel(new Vector3(-contentHalfW + padding * 0.9f, titleY, 0f), terminalTitle, colWhiteGlow, fontSize * 0.74f);
Color separator = colWhiteGlow;
separator.a *= Alpha * textReveal * 0.26f;
Handles.color = separator;
Handles.DrawLine(
new Vector3(-halfW, separatorY, 0f),
new Vector3(halfW, separatorY, 0f));
float topY = GetContentTopY(currentSize);
float bottomY = -contentHalfH + padding * 0.88f;
int visibleLineBudget = Mathf.Max(1, Mathf.FloorToInt((topY - bottomY) / lineHeight));
int visibleLines = Mathf.Min(maxVisibleLines, visibleLineBudget);
List<RenderRow> rows = BuildRenderRows();
int startIdx = Mathf.Max(0, rows.Count - visibleLines);
for (int i = startIdx; i < rows.Count; i++)
{
int row = i - startIdx;
float y = topY - row * lineHeight;
RenderRow renderRow = rows[i];
Color c = renderRow.color;
c.a *= Alpha * textReveal;
string displayText = renderRow.text;
if (renderRow.hasCursorSlot)
displayText += renderRow.showCursor ? "\u2588" : " ";
DrawEditorLabel(new Vector3(-contentHalfW + padding, y, 0f), displayText, c, fontSize);
}
Handles.matrix = previousMatrix;
Handles.color = previousColor;
Handles.zTest = previousZTest;
}
private void DrawEditorLabel(Vector3 localPosition, string text, Color color, float worldFontSize)
{
if (string.IsNullOrEmpty(text))
return;
if (_editorPreviewLabelStyle == null)
{
_editorPreviewLabelStyle = new GUIStyle(EditorStyles.label)
{
alignment = TextAnchor.UpperLeft,
richText = false
};
if (terminalFont != null && terminalFont.sourceFontFile != null)
_editorPreviewLabelStyle.font = terminalFont.sourceFontFile;
}
_editorPreviewLabelStyle.fontSize = Mathf.Clamp(Mathf.RoundToInt(worldFontSize * 12f), 8, 28);
_editorPreviewLabelStyle.normal.textColor = color;
Handles.Label(localPosition, text, _editorPreviewLabelStyle);
}
private void EditorPreviewUpdate()
{
if (Application.isPlaying || !previewInEditor || !NeedsAnimatedEditorRepaint())
return;
double now = EditorApplication.timeSinceStartup;
float interval = Mathf.Max(0.08f, cursorBlinkRate);
if (now - _editorLastRepaintTime < interval)
return;
_editorLastRepaintTime = now;
SceneView.RepaintAll();
}
private bool NeedsAnimatedEditorRepaint()
{
return animatePreviewCursor && previewStage == PreviewStage.WaitingInput;
}
private void ApplyEditorPreviewState()
@@ -945,6 +1079,7 @@ namespace AibisDream.UI
_typingCurrent = "";
_inputBuffer = "";
_cursorVisible = false;
DrawCommand.ClearAllCommands();
return;
}