- Home /
Question by
h00man · May 17 at 06:54 PM ·
physicscollision detectionlinerendererropecolider
line renderer collision detection in 3D
hello guys so i been using the code down below to simulate a rope physics .based on this tutorial
https://www.youtube.com/watch?v=k32g4ujzxP0&t=55s
currently it uses edge collider 2d to detect collision. i was wondering if there was way to make it to work in 3D as well . any sorta 3d collision would be great just to make the rope not to go through objects in the scene. here the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RopeBridge : MonoBehaviour
{
public Transform StartPoint;
public Transform EndPoint;
private LineRenderer lineRenderer;
public List<RopeSegment> ropeSegments = new List<RopeSegment>();
public Vector3 forceGravity;
Vector3 ropeStartPoint;
[Range(.0f, .1f)] public float ropeSegLen = 0.25f;
[Range(1f, 100f)] public int segmentLength ;
public float lineWidth = 0.1f;
Vector3 changeAmount;
private Vector3 changeDir;
private Vector3 changeAmoun;
private Vector3 velocity;
[Range(.0f, 1f)] public float ropeVelocity;
public List<Vector2> newVerticies = new List<Vector2>();
private EdgeCollider2D col;
void Start()
{
col = GetComponent<EdgeCollider2D>();
this.lineRenderer = this.GetComponent<LineRenderer>();
ropeStartPoint = StartPoint.position;
for (int i = 0; i < segmentLength; i++)
{
this.ropeSegments.Add(new RopeSegment(ropeStartPoint));
ropeStartPoint.y -= ropeSegLen;
newVerticies.Add(new Vector2(ropeStartPoint.x, ropeStartPoint.y));
}
col.points = newVerticies.ToArray();
}
// Update is called once per frame
void Update()
{
this.DrawRope();
}
private void FixedUpdate()
{
this.Simulate();
}
private void Simulate()
{
// SIMULATION
// forceGravity = new Vector2(0f, -1f);
for (int i = 1; i < this.segmentLength; i++)
{
RopeSegment firstSegment = this.ropeSegments[i];
velocity = firstSegment.posNow - firstSegment.posOld;
firstSegment.posOld = firstSegment.posNow;
firstSegment.posNow += velocity = new Vector3(velocity.x * ropeVelocity, velocity.y * ropeVelocity, velocity.z * ropeVelocity); // velcoty
firstSegment.posNow += forceGravity * Time.fixedDeltaTime;
this.ropeSegments[i] = firstSegment;
}
//CONSTRAINTS
for (int i = 0; i < 50; i++)
{
this.ApplyConstraint();
}
}
private void ApplyConstraint()
{
//Constrant to First Point
RopeSegment firstSegment = this.ropeSegments[0];
firstSegment.posNow = this.StartPoint.position;
this.ropeSegments[0] = firstSegment;
//Constrant to Second Point
RopeSegment endSegment = this.ropeSegments[this.ropeSegments.Count - 1];
endSegment.posNow = this.EndPoint.position;
this.ropeSegments[this.ropeSegments.Count - 1] = endSegment;
for (int i = 0; i < this.segmentLength - 1; i++)
{
RopeSegment firstSeg = this.ropeSegments[i];
RopeSegment secondSeg = this.ropeSegments[i + 1];
float dist = (firstSeg.posNow - secondSeg.posNow).magnitude;
float error = Mathf.Abs(dist - this.ropeSegLen);
changeDir = Vector2.zero;
if (dist > ropeSegLen)
{
changeDir = (firstSeg.posNow - secondSeg.posNow).normalized;
}
else if (dist < ropeSegLen)
{
changeDir = (secondSeg.posNow - firstSeg.posNow).normalized;
}
changeAmount = changeDir * error;
if (i != 0)
{
firstSeg.posNow -= changeAmount * 0.5f;
this.ropeSegments[i] = firstSeg;
secondSeg.posNow += changeAmount * 0.5f;
this.ropeSegments[i + 1] = secondSeg;
}
else
{
secondSeg.posNow += changeAmount;
this.ropeSegments[i + 1] = secondSeg;
}
newVerticies[i] = this.ropeSegments[i].posNow;
//ADDITION
}
col.points = newVerticies.ToArray();
//ADDITION
}
private void DrawRope()
{
float lineWidth = this.lineWidth;
lineRenderer.startWidth = lineWidth;
lineRenderer.endWidth = lineWidth;
Vector3[] ropePositions = new Vector3[this.segmentLength];
for (int i = 0; i < this.segmentLength; i++)
{
ropePositions[i] = this.ropeSegments[i].posNow;
newVerticies[i] = this.ropeSegments[i].posNow;
}
lineRenderer.positionCount = ropePositions.Length;
lineRenderer.SetPositions(ropePositions);
col.points = newVerticies.ToArray();
}
public struct RopeSegment
{
public Vector3 posNow;
public Vector3 posOld;
public RopeSegment(Vector3 pos)
{
this.posNow = pos;
this.posOld = pos;
}
}
}
Comment
Your answer
Follow this Question
Related Questions
Creating a dynamic fishing line with line rendering, but the last segment is stiff? 0 Answers
Problem with TriggerEnter/Exit Execution Order 0 Answers
Hinge Joint Giving Fake 'Slack' 0 Answers
Platform collisions only from above in 2D 1 Answer
How to create a freely swinging "rope" of modifiable size between two rigid bodies? 0 Answers