Last active
February 25, 2025 18:57
-
-
Save koster/1b69577d94eb58cbaedd0c8182cc17f6 to your computer and use it in GitHub Desktop.
ChatGPT verlet rope
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
public class VerletRope : MonoBehaviour | |
{ | |
public Transform startPoint; // Начальная точка верёвки | |
public Transform endPoint; // Конечная точка верёвки | |
public int segmentCount = 10; // Количество сегментов верёвки | |
public float segmentLength = 0.2f; // Длина каждого сегмента | |
public int simulationIterations = 5; // Количество итераций симуляции | |
public float gravity = -9.8f; // Гравитация | |
private Vector3[] positions; | |
private Vector3[] oldPositions; | |
private LineRenderer lineRenderer; | |
void Start() | |
{ | |
lineRenderer = GetComponent<LineRenderer>(); | |
lineRenderer.positionCount = segmentCount; | |
positions = new Vector3[segmentCount]; | |
oldPositions = new Vector3[segmentCount]; | |
// Инициализация точек верёвки | |
Vector3 ropeDirection = (endPoint.position - startPoint.position).normalized; | |
for (int i = 0; i < segmentCount; i++) | |
{ | |
positions[i] = startPoint.position + ropeDirection * segmentLength * i; | |
oldPositions[i] = positions[i]; | |
} | |
} | |
void Update() | |
{ | |
SimulateVerlet(); | |
ApplyConstraints(); | |
UpdateLineRenderer(); | |
} | |
private void SimulateVerlet() | |
{ | |
for (int i = 1; i < segmentCount; i++) // Не трогаем первую точку | |
{ | |
Vector3 currentPos = positions[i]; | |
Vector3 velocity = currentPos - oldPositions[i]; | |
oldPositions[i] = currentPos; | |
positions[i] += velocity + new Vector3(0, gravity * Time.deltaTime, 0) * Time.deltaTime; | |
} | |
} | |
private void ApplyConstraints() | |
{ | |
// Первая и последняя точки прикреплены к объектам | |
positions[0] = startPoint.position; | |
positions[segmentCount - 1] = endPoint.position; | |
// Обработка всех сегментов | |
for (int k = 0; k < simulationIterations; k++) | |
{ | |
for (int i = 0; i < segmentCount - 1; i++) | |
{ | |
Vector3 segmentVector = positions[i + 1] - positions[i]; | |
float currentLength = segmentVector.magnitude; | |
float error = (currentLength - segmentLength) / currentLength; | |
Vector3 correction = segmentVector * 0.5f * error; | |
// Перемещаем точки | |
if (i > 0) | |
{ | |
positions[i] += correction; | |
} | |
if (i + 1 < segmentCount - 1) | |
{ | |
positions[i + 1] -= correction; | |
} | |
} | |
} | |
} | |
private void UpdateLineRenderer() | |
{ | |
lineRenderer.SetPositions(positions); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment