AdaptiveElectricArc.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. [RequireComponent(typeof(Transform))]
  4. public class AdaptiveElectricArc : MonoBehaviour
  5. {
  6. [Header("Arc Points")]
  7. public Transform pointA;
  8. public Transform pointB;
  9. [Header("Arc Settings")]
  10. public int arcCount = 3;
  11. public float segmentSpacing = 0.1f; // 每段长度
  12. public float arcAmplitude = 0.2f;
  13. public float noiseSpeed = 10f;
  14. public float updateInterval = 0.05f;
  15. public float arcWidth = 0.05f;
  16. [Header("Flicker Settings")]
  17. public bool enableFlicker = true;
  18. public float flickerInterval = 0.1f;
  19. [Header("Color Gradient")]
  20. public Gradient arcColorGradient;
  21. public Material material;
  22. private List<LineRenderer> arcs = new List<LineRenderer>();
  23. private float updateTimer = 0f;
  24. private float flickerTimer = 0f;
  25. void Start()
  26. {
  27. for (int i = 0; i < arcCount; i++)
  28. {
  29. GameObject arcObj = new GameObject("Arc_" + i);
  30. arcObj.transform.parent = transform;
  31. LineRenderer lr = arcObj.AddComponent<LineRenderer>();
  32. lr.material = material;
  33. lr.widthMultiplier = arcWidth;
  34. lr.colorGradient = arcColorGradient;
  35. lr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
  36. lr.receiveShadows = false;
  37. lr.useWorldSpace = true;
  38. arcs.Add(lr);
  39. }
  40. }
  41. void Update()
  42. {
  43. updateTimer += Time.deltaTime;
  44. flickerTimer += Time.deltaTime;
  45. // 更新电弧形状
  46. if (updateTimer >= updateInterval)
  47. {
  48. foreach (var arc in arcs)
  49. {
  50. GenerateArc(arc);
  51. }
  52. updateTimer = 0f;
  53. }
  54. // 电弧闪烁
  55. if (enableFlicker && flickerTimer >= flickerInterval)
  56. {
  57. foreach (var arc in arcs)
  58. {
  59. arc.enabled = Random.value > 0.3f;
  60. }
  61. flickerTimer = 0f;
  62. }
  63. }
  64. void GenerateArc(LineRenderer lr)
  65. {
  66. if (pointA == null || pointB == null) return;
  67. Vector3 start = pointA.position;
  68. Vector3 end = pointB.position;
  69. Vector3 dir = (end - start).normalized;
  70. float length = Vector3.Distance(start, end);
  71. // 自适应段数
  72. int segmentCount = Mathf.Max(2, Mathf.RoundToInt(length / segmentSpacing));
  73. lr.positionCount = segmentCount;
  74. // 正交扰动方向
  75. Vector3 right = Vector3.Cross(dir, Vector3.up).normalized;
  76. Vector3 up = Vector3.Cross(right, dir).normalized;
  77. for (int i = 0; i < segmentCount; i++)
  78. {
  79. float t = (float)i / (segmentCount - 1);
  80. Vector3 point = Vector3.Lerp(start, end, t);
  81. // 距离越大 → 抖动越大;中段抖动更多
  82. float noise = Mathf.PerlinNoise(Time.time * noiseSpeed + i, Random.Range(0f, 100f)) * 2f - 1f;
  83. float localAmplitude = Mathf.Lerp(0.01f, arcAmplitude, length);
  84. float sinOffset = Mathf.Sin(t * Mathf.PI); // 中间最大
  85. Vector3 offset = (right + up) * noise * localAmplitude * sinOffset;
  86. lr.SetPosition(i, point + offset);
  87. }
  88. }
  89. }