using UnityEngine; using System.Collections.Generic; [RequireComponent(typeof(Transform))] public class AdaptiveElectricArc : MonoBehaviour { [Header("Arc Points")] public Transform pointA; public Transform pointB; [Header("Arc Settings")] public int arcCount = 3; public float segmentSpacing = 0.1f; // 每段长度 public float arcAmplitude = 0.2f; public float noiseSpeed = 10f; public float updateInterval = 0.05f; public float arcWidth = 0.05f; [Header("Flicker Settings")] public bool enableFlicker = true; public float flickerInterval = 0.1f; [Header("Color Gradient")] public Gradient arcColorGradient; public Material material; private List arcs = new List(); private float updateTimer = 0f; private float flickerTimer = 0f; void Start() { for (int i = 0; i < arcCount; i++) { GameObject arcObj = new GameObject("Arc_" + i); arcObj.transform.parent = transform; LineRenderer lr = arcObj.AddComponent(); lr.material = material; lr.widthMultiplier = arcWidth; lr.colorGradient = arcColorGradient; lr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; lr.receiveShadows = false; lr.useWorldSpace = true; arcs.Add(lr); } } void Update() { updateTimer += Time.deltaTime; flickerTimer += Time.deltaTime; // 更新电弧形状 if (updateTimer >= updateInterval) { foreach (var arc in arcs) { GenerateArc(arc); } updateTimer = 0f; } // 电弧闪烁 if (enableFlicker && flickerTimer >= flickerInterval) { foreach (var arc in arcs) { arc.enabled = Random.value > 0.3f; } flickerTimer = 0f; } } void GenerateArc(LineRenderer lr) { if (pointA == null || pointB == null) return; Vector3 start = pointA.position; Vector3 end = pointB.position; Vector3 dir = (end - start).normalized; float length = Vector3.Distance(start, end); // 自适应段数 int segmentCount = Mathf.Max(2, Mathf.RoundToInt(length / segmentSpacing)); lr.positionCount = segmentCount; // 正交扰动方向 Vector3 right = Vector3.Cross(dir, Vector3.up).normalized; Vector3 up = Vector3.Cross(right, dir).normalized; for (int i = 0; i < segmentCount; i++) { float t = (float)i / (segmentCount - 1); Vector3 point = Vector3.Lerp(start, end, t); // 距离越大 → 抖动越大;中段抖动更多 float noise = Mathf.PerlinNoise(Time.time * noiseSpeed + i, Random.Range(0f, 100f)) * 2f - 1f; float localAmplitude = Mathf.Lerp(0.01f, arcAmplitude, length); float sinOffset = Mathf.Sin(t * Mathf.PI); // 中间最大 Vector3 offset = (right + up) * noise * localAmplitude * sinOffset; lr.SetPosition(i, point + offset); } } }