using UnityEngine; using System.Collections.Generic; using Shapes; namespace AibisDream.MiniGame.Language { /// /// 连接线渲染器:使用Shapes绘制粒子间的连接线 /// [ExecuteAlways] public class ConnectionRenderer : ImmediateModeShapeDrawer { [Header("引用")] public LanguageParticleManager manager; [Header("连接线设置")] public float connectionDistance = 2f; public Color blueConnectionColor = new Color(0.39f, 0.78f, 1f, 0.7f); public Color redConnectionColor = new Color(1f, 0.39f, 0.39f, 1f); public float blueLineThickness = 0.02f; public float redLineThickness = 0.04f; [Header("效果传播设置")] public Color propagationColor = new Color(1f, 0.59f, 0.2f, 1f); public float propagationLineThickness = 0.03f; private List candidateParticles; private List effectPropagations; private CompletionPhase completionPhase; private float fadeOutAlpha; public void SetData( List candidates, List 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; // 绘制蓝色粒子间的连线 if (completionPhase == CompletionPhase.None || completionPhase == CompletionPhase.Arranging) { DrawBlueConnections(); } // 绘制红色粒子间的连线 if (completionPhase == CompletionPhase.None || completionPhase == CompletionPhase.Arranging) { DrawRedConnections(); } // 绘制效果传播线 if (effectPropagations != null && effectPropagations.Count > 0) { DrawPropagationEffects(); } } } private void DrawBlueConnections() { Draw.LineGeometry = LineGeometry.Flat2D; Draw.Thickness = blueLineThickness; 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 = blueConnectionColor; lineColor.a = alpha; Draw.Line(p1.transform.position, p2.transform.position, lineColor); } } } } private void DrawRedConnections() { Draw.LineGeometry = LineGeometry.Flat2D; Draw.Thickness = redLineThickness; var redParticles = new List(); 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 = redConnectionColor; lineColor.a = alpha; 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); } } }