| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- 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<LineRenderer> arcs = new List<LineRenderer>();
- 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<LineRenderer>();
- 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);
- }
- }
- }
|