Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by AsclepiiusUnknown · Jul 03, 2020 at 04:36 AM · unity 2dropeedgemathselastic

Verlet Elastic Collision

Hey all, I'm working on a game and over the last few days I've taken a script from here about making rope bridges using verlet integration. So far I've added a 2D edge collider to the object and it all works fine, currently it just creates an object at the Collison point and gets the index of said point. What I'm aiming to do is have an object (eg. My square player) move along it like a ground and I want the shape of the rope to alter accordingly. I was thinking of having an elasticity variable and getting the mass and gravity force from the players rigidbody but I can't think of how to do this. My script is below:

 public Transform StartPoint;
     public Transform EndPoint;
 
     public bool useCollider = true;
 
     private LineRenderer lineRenderer;
     private List<RopeSegment> ropeSegments = new List<RopeSegment>();
     public float ropeSegLen = 0.25f;
     public int segmentCount = 35;
     public float lineWidth = 0.1f;
 
     //Sling Shot
     bool moveToMouse = false;
     Vector3 mousePositionWorld;
     int indexMousePos;
     //Gameobject following
     //public GameObject followObject;
 
     public EdgeCollider2D edgeCollider;
 
 
     // Use this for initialization
     void Start()
     {
         this.lineRenderer = this.GetComponent<LineRenderer>();
         Vector3 ropeStartPoint = StartPoint.position;
 
         for (int i = 0; i < segmentCount; i++)
         {
             this.ropeSegments.Add(new RopeSegment(ropeStartPoint));
             ropeStartPoint.y -= ropeSegLen;
         }
 
         if (useCollider && edgeCollider != null)
         {
             edgeCollider.enabled = true;
             edgeCollider.edgeRadius = lineWidth / 2;
         }
         else
             edgeCollider.enabled = false;
     }
 
     // Update is called once per frame
     void Update()
     {
         this.DrawRope();
 
         if (Input.GetMouseButtonDown(0))
         {
             this.moveToMouse = true;
         }
         else if (Input.GetMouseButtonUp(0))
         {
             this.moveToMouse = false;
         }
 
         Vector3 screenMousePos = Input.mousePosition;
         float xStart = StartPoint.position.x;
         float xEnd = EndPoint.position.x;
         this.mousePositionWorld = Camera.main.ScreenToWorldPoint(new Vector3(screenMousePos.x, screenMousePos.y, 10));
         float currX = this.mousePositionWorld.x; //followObject.transform.position.x
 
         float ratio = (currX - xStart) / (xEnd - xStart);
         if (ratio > 0)
         {
             this.indexMousePos = (int)(this.segmentCount * ratio);
         }
     }
 
     private void FixedUpdate()
     {
         this.Simulate();
     }
 
     private void OnCollisionEnter2D(Collision2D other)
     {
         int closestIndex = 805;
         float closestDist = float.MaxValue;
 
         for (int i = 0; i < edgeCollider.points.Length; i++)
         {
             Vector2 edgePoint = edgeCollider.points[i];
 
             float thisDist = Vector2.Distance(edgePoint, other.GetContact(0).point);
 
             if (thisDist < closestDist)
             {
                 closestDist = thisDist;
                 closestIndex = i;
             }
         }
 
         #region TESTING //!REMOVE LATER
         print(closestIndex);
         GameObject go = new GameObject();
         go.transform.position = edgeCollider.points[closestIndex];
         go.name = "Collision w/ Point " + closestIndex;
         #endregion
     }
 
     private void Simulate()
     {
         // SIMULATION
         Vector2 forceGravity = new Vector2(0f, -1f);
 
         for (int i = 1; i < this.segmentCount; i++)
         {
             RopeSegment firstSegment = this.ropeSegments[i];
             Vector2 velocity = firstSegment.posNow - firstSegment.posOld;
             firstSegment.posOld = firstSegment.posNow;
             firstSegment.posNow += velocity;
             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.segmentCount - 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);
             Vector2 changeDir = Vector2.zero;
 
             if (dist > ropeSegLen)
             {
                 changeDir = (firstSeg.posNow - secondSeg.posNow).normalized;
             }
             else if (dist < ropeSegLen)
             {
                 changeDir = (secondSeg.posNow - firstSeg.posNow).normalized;
             }
 
             Vector2 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;
             }
             //*
             Vector2[] colliderPoints = new Vector2[this.segmentCount];
             colliderPoints[i] = this.ropeSegments[i].posNow;
 
             if (this.moveToMouse && indexMousePos > 0 && indexMousePos < this.segmentCount - 1 && i == indexMousePos)
             {
                 RopeSegment thisSegment = this.ropeSegments[i];
                 RopeSegment nextSegment = this.ropeSegments[i + 1];
                 thisSegment.posNow = new Vector2(this.mousePositionWorld.x, this.mousePositionWorld.y);
                 nextSegment.posNow = new Vector2(this.mousePositionWorld.x, this.mousePositionWorld.y);
                 // thisSegment.posNow = new Vector2 (this.followObject.transform.position.x, this.followObject.transform.position.y);
                 // nextSegment.posNow = new Vector2 (this.followObject.transform.position.x, this.followObject.transform.position.y);
                 this.ropeSegments[i] = thisSegment;
                 this.ropeSegments[i + 1] = nextSegment;
             }
 
             if (edgeCollider.points.Length == 0)
                 print("**NULL**");
             else
                 edgeCollider.points[i] = colliderPoints[i];
         }
     }
 
     private void DrawRope()
     {
         float lineWidth = this.lineWidth;
         lineRenderer.startWidth = lineWidth;
         lineRenderer.endWidth = lineWidth;
 
         Vector3[] ropePositions = new Vector3[this.segmentCount];
 
         for (int i = 0; i < this.segmentCount; i++)
         {
             ropePositions[i] = this.ropeSegments[i].posNow;
         }
 
         lineRenderer.positionCount = ropePositions.Length;
         lineRenderer.SetPositions(ropePositions);
 
         if (useCollider)
             CreateColliders();
     }
 
     private void CreateColliders()
     {
         Vector2[] colliderPoints = new Vector2[this.segmentCount];
 
         for (int i = 0; i < this.segmentCount; i++)
         {
             colliderPoints[i] = this.ropeSegments[i].posNow;
         }
 
         edgeCollider.points = colliderPoints;
     }
 
     public struct RopeSegment
     {
         public Vector2 posNow;
         public Vector2 posOld;
 
         public RopeSegment(Vector2 pos)
         {
             this.posNow = pos;
             this.posOld = pos;
         }
     }

My posts barely get read but if anyone sees this and helps I would be so appreciative, thanks in advance!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

135 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to build upon Jongallant's verlet integration rope project 0 Answers

EdgeCollider2D.points returnes Values of wrong gameObject 1 Answer

How can I allow the rope to correctly interact with Box and Polygon colliders? 0 Answers

how can i limit my rope? 0 Answers

unity 2D with delay run and jump 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges