Files
aibis-dream/Assets/Scripts/MiniGame/HuoShan/Language/ConnectionRenderer.cs
T
2025-11-13 20:30:13 +08:00

248 lines
9.1 KiB
C#
Raw 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 UnityEngine;
using System.Collections.Generic;
using Shapes;
namespace AibisDream.MiniGame.Language
{
/// <summary>
/// 连接线渲染器:使用Shapes绘制粒子间的连接线
/// 注意:sortingOrder 设置为 0,确保低于文字(文字 sortingOrder = 10
/// </summary>
[ExecuteAlways]
public class ConnectionRenderer : ImmediateModeShapeDrawer
{
[Header("引用")]
public LanguageParticleManager manager;
[Header("连接线设置")]
public float connectionDistance = 2f;
private Color nonTargetConnectionColor = new Color(0.39f, 0.78f, 1f, 0.7f); // 非目标粒子连线颜色
private Color targetConnectionColor = new Color(1f, 0.39f, 0.39f, 1f); // 目标粒子连线颜色
private float nonTargetLineThickness = 0.02f;
private float targetLineThickness = 0.04f;
[Header("效果传播设置")]
private Color propagationColor = new Color(1f, 0.59f, 0.2f, 1f);
private float propagationLineThickness = 0.03f;
private List<CandidateParticle> candidateParticles;
private List<EffectPropagation> effectPropagations;
private CompletionPhase completionPhase;
private float fadeOutAlpha;
private float nonTargetAlphaScale = 1f;
private float targetAlphaScale = 1f;
public float NonTargetAlphaScale
{
get => nonTargetAlphaScale;
set => nonTargetAlphaScale = Mathf.Clamp01(value);
}
public float TargetAlphaScale
{
get => targetAlphaScale;
set => targetAlphaScale = Mathf.Clamp(value, 0f, 1.5f);
}
public void SetData(
List<CandidateParticle> candidates,
List<EffectPropagation> propagations,
CompletionPhase phase,
float fadeAlpha)
{
candidateParticles = candidates;
effectPropagations = propagations;
completionPhase = phase;
fadeOutAlpha = fadeAlpha;
}
public override void DrawShapes(Camera cam)
{
if (candidateParticles == null || candidateParticles.Count == 0)
return;
using (Draw.Command(cam))
{
Draw.BlendMode = ShapesBlendMode.Transparent;
Draw.ZTest = UnityEngine.Rendering.CompareFunction.Always;
// 注意:连接线默认在底层,文字的 sortingOrder = 10 会显示在上层
// 绘制蓝色粒子间的连线
if (completionPhase == CompletionPhase.None || completionPhase == CompletionPhase.Completed)
{
DrawBlueConnections();
}
// 绘制红色粒子间的连线
if (completionPhase == CompletionPhase.None ||
completionPhase == CompletionPhase.Completed ||
completionPhase == CompletionPhase.Focusing)
{
DrawRedConnections();
}
// 绘制效果传播线
if (effectPropagations != null && effectPropagations.Count > 0)
{
DrawPropagationEffects();
}
}
}
private void DrawBlueConnections()
{
Draw.LineGeometry = LineGeometry.Flat2D;
Draw.Thickness = nonTargetLineThickness;
for (int i = 0; i < candidateParticles.Count; i++)
{
for (int j = i + 1; j < candidateParticles.Count; j++)
{
var p1 = candidateParticles[i];
var p2 = candidateParticles[j];
// 跳过红色粒子
if (p1.isRed && p2.isRed) continue;
float distance = Vector3.Distance(p1.transform.position, p2.transform.position);
if (distance < connectionDistance)
{
float alpha = Mathf.Lerp(0.7f, 0f, distance / connectionDistance) * fadeOutAlpha;
Color lineColor = nonTargetConnectionColor;
lineColor.a = alpha * nonTargetAlphaScale;
Draw.Line(p1.transform.position, p2.transform.position, lineColor);
}
}
}
}
private void DrawRedConnections()
{
Draw.LineGeometry = LineGeometry.Flat2D;
Draw.Thickness = targetLineThickness;
var redParticles = new List<CandidateParticle>();
foreach (var p in candidateParticles)
{
if (p.isRed)
redParticles.Add(p);
}
for (int i = 0; i < redParticles.Count; i++)
{
for (int j = i + 1; j < redParticles.Count; j++)
{
float distance = Vector3.Distance(
redParticles[i].transform.position,
redParticles[j].transform.position
);
if (distance < connectionDistance)
{
float alpha = Mathf.Lerp(1f, 0.4f, distance / connectionDistance);
Color lineColor = targetConnectionColor;
lineColor.a = alpha * targetAlphaScale;
Draw.Line(redParticles[i].transform.position, redParticles[j].transform.position, lineColor);
}
}
}
}
private void DrawPropagationEffects()
{
Draw.LineGeometry = LineGeometry.Flat2D;
Draw.Thickness = propagationLineThickness;
foreach (var propagation in effectPropagations)
{
if (propagation.PropagatedParticles == null) continue;
foreach (var info in propagation.PropagatedParticles)
{
if (info.source == null || info.particle == null) continue;
// 绘制连接线
Color lineColor = propagationColor;
lineColor.a = 0.3f;
Draw.Line(info.source.transform.position, info.particle.transform.position, lineColor);
// 绘制脉冲光点
if (info.pulseProgress < 1f)
{
Vector3 pulsePos = Vector3.Lerp(
info.source.transform.position,
info.particle.transform.position,
info.pulseProgress
);
float pulseSize = Mathf.Lerp(0.03f, 0.08f, info.pulseProgress);
float pulseAlpha = Mathf.Lerp(1f, 0f, info.pulseProgress);
Color pulseColor = new Color(1f, 0.78f, 0.39f, pulseAlpha);
Draw.Ring(pulsePos, pulseSize, pulseSize * 0.5f, pulseColor);
// 光晕
pulseColor.a = pulseAlpha * 0.5f;
Draw.Disc(pulsePos, pulseSize * 1.5f, pulseColor);
}
// 绘制箭头
if (info.pulseProgress > 0.5f && info.pulseProgress < 1f)
{
Vector3 arrowPos = Vector3.Lerp(
info.source.transform.position,
info.particle.transform.position,
0.5f
);
Vector3 direction = (info.particle.transform.position - info.source.transform.position).normalized;
float angle = Mathf.Atan2(direction.y, direction.x);
Color arrowColor = new Color(1f, 0.78f, 0.39f, 0.8f);
DrawArrow(arrowPos, angle, 0.1f, arrowColor);
}
}
}
}
private void DrawArrow(Vector3 position, float angle, float size, Color color)
{
Vector3 tip = position + new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0) * size;
Vector3 left = position + new Vector3(
Mathf.Cos(angle + 2.5f),
Mathf.Sin(angle + 2.5f),
0
) * size * 0.5f;
Vector3 right = position + new Vector3(
Mathf.Cos(angle - 2.5f),
Mathf.Sin(angle - 2.5f),
0
) * size * 0.5f;
Draw.Triangle(tip, left, right, color);
}
/// <summary>
/// 设置连接线样式
/// </summary>
public void SetConnectionStyles(
Color targetColor,
Color nonTargetColor,
Color propColor,
float targetThickness,
float nonTargetThickness,
float propThickness)
{
targetConnectionColor = targetColor;
nonTargetConnectionColor = nonTargetColor;
propagationColor = propColor;
targetLineThickness = targetThickness;
nonTargetLineThickness = nonTargetThickness;
propagationLineThickness = propThickness;
}
}
}