feat(frameAnima): 动画系统前四个阶段
This commit is contained in:
@@ -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 Handles,URP 下 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user