using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(LineRenderer))] public class PhysicLineSegment : MonoBehaviour { public float segmentSpacing = 0.1f; public int k = 30; public List particles = new(); private List sticks = new(); [HideInInspector] public LineRenderer lineRenderer; private int segmentCount; public float gravity = -9.8f; private float originalLength; public void Initialize(Vector3 start, Vector3 end) { particles.Clear(); sticks.Clear(); if (lineRenderer != null) { lineRenderer.positionCount = 0; } originalLength = Vector3.Distance(start, end); segmentCount = Mathf.RoundToInt(originalLength / segmentSpacing); lineRenderer = GetComponent(); // Initialize particles for (int i = 0; i < segmentCount; i++) { var particle = new VerletParticle(Vector3.Lerp(start, end, i / (float)segmentCount)); particles.Add(particle); } // Initialize sticks for (int i = 0; i < segmentCount - 1; i++) { sticks.Add(new VerletStick(particles[i], particles[i + 1], segmentSpacing)); } // Lock the first particle particles[0].isLocked = true; lineRenderer.positionCount = segmentCount; } void FixedUpdate() { UpdateLine(); for (int i = 0; i < segmentCount; i++) { if (lineRenderer != null) { lineRenderer.SetPosition(i, particles[i].position); } } } void UpdateLine() { // Apply gravity to particles for (int i = 1; i < particles.Count; i++) { particles[i].ApplyForce(Vector3.up * gravity * Time.deltaTime); particles[i].UpdatePosition(); } // Update sticks for (int ik = 0; ik < k; ik++) { foreach (var stick in sticks) { stick.UpdateStick(); } } } public void UpdatePlug(Transform plug) { if (plug && particles.Count > 1) { Vector3 plugPosition = particles[^1].position; float plugLength = plug.GetComponent().bounds.size.y; Vector3 direction = particles[^1].position - particles[^2].position; float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg; plug.rotation = Quaternion.Euler(0, 0, angle - 90f); plug.position = plugPosition + direction.normalized * (plugLength / 2); } } public void UpdateStart(Vector3 newStartPosition) { if (particles.Count > 0) { particles[0].position = newStartPosition; } } }