Files
aibis-dream/Assets/Scripts/FixSystemNew/Cable/PhysicLineSegment.cs
T

103 lines
2.8 KiB
C#

using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class PhysicLineSegment : MonoBehaviour
{
public float segmentSpacing = 0.1f;
public int k = 30;
public List<VerletParticle> particles = new();
private List<VerletStick> 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<LineRenderer>();
// 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<SpriteRenderer>().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;
}
}
}