private void ApplyConstraints() { float constraintLength = RestLength / ((ropeNodes.Count - 1) + 2); VerletRopeNode n0 = this.ropeNodes[0]; Vector3 d1 = n0.transform.position - transform.position; float d2 = d1.magnitude; float d3 = (d2 - constraintLength) / d2; n0.transform.position += -1.0f * d1 * d3; for (int i = 0; i < ropeNodes.Count - 1; i++) { VerletRopeNode node1 = this.ropeNodes[i]; VerletRopeNode node2 = this.ropeNodes[i + 1]; Vector3 x1 = node1.transform.position; Vector3 x2 = node2.transform.position; d1 = x2 - x1; d2 = d1.magnitude; d3 = (d2 - constraintLength) / d2; node1.transform.position = x1 + 0.5f * d1 * d3; node2.transform.position = x2 - 0.5f * d1 * d3; } VerletRopeNode nLast = this.ropeNodes[this.ropeNodes.Count - 1]; d1 = connectedTrans.position - nLast.transform.position; d2 = d1.magnitude; d3 = (d2 - constraintLength) / d2; nLast.transform.position += 1.0f * d1 * d3; }
void Awake() { Camera = Camera.main; LineRenderer = this.GetComponent <LineRenderer>(); // Generate some rope nodes based on properties Vector3 startPosition = Vector2.zero; Vector3 endPosition = Vector2.zero - new Vector2(0, NodeDistance * TotalNodes); Vector3 dir = Vector3.zero; float angle = 270; if (nodeStartAnchor) { startPosition = nodeStartAnchor.position; } if (nodeEndAnchor) { endPosition = nodeEndAnchor.position; } if (nodeStartAnchor && nodeEndAnchor) { anchorDistance = Vector3.Distance(nodeStartAnchor.transform.position, nodeEndAnchor.transform.position); TotalNodes = (int)Math.Ceiling(anchorDistance / NodeDistance); dir = nodeEndAnchor.transform.position - nodeStartAnchor.transform.position; angle = (Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg);// + 90; } for (int i = 0; i < TotalNodes; i++) { Vector3 pos = Vector3.MoveTowards(startPosition, endPosition, NodeDistance * i); VerletRopeNode node = GameObject.Instantiate(nodePrefab, pos, Quaternion.identity).GetComponent <VerletRopeNode>(); node.transform.position = startPosition; node.PreviousPosition = startPosition; RopeNodes.Add(node); startPosition = pos; } // for line renderer data LinePositions = new Vector3[TotalNodes]; //Add a distance joint to limit the maximum amount of distance myDJ = nodeStartAnchor.gameObject.AddComponent <DistanceJoint2D>(); myDJ.connectedBody = nodeEndAnchor.GetComponent <Rigidbody2D>(); //myDJ.anchor = nodeStartAnchor.position; //myDJ.connectedAnchor = nodeEndAnchor.position; myDJ.maxDistanceOnly = true; myDJ.breakForce = Mathf.Infinity; myDJ.breakTorque = Mathf.Infinity; myDJ.enableCollision = false; myDJ.autoConfigureDistance = false; myDJ.autoConfigureConnectedAnchor = false; myDJ.distance = Vector3.Distance(nodeStartAnchor.position, nodeEndAnchor.position) * 2; }
public void BuildRope(Transform connectedTrans, int numSegments, float maxRestLength, Material ropeMat) { float distance = Vector3.Distance(transform.position, connectedTrans.position); float constraintLength = distance / numSegments; Vector3 direction = connectedTrans.position - transform.position; for (int i = 1; i < numSegments; i++) { Vector3 pos = Vector3.Lerp(transform.position, connectedTrans.position, i * constraintLength / distance); GameObject ropeNodeGO = new GameObject(); ropeNodeGO.transform.position = pos; VerletRopeNode ropeNode = ropeNodeGO.AddComponent <VerletRopeNode>(); ropeNode.previousPosition = pos; ropeNodes.Add(ropeNode); } this.maxRestLength = maxRestLength; ropeRenderer.material = ropeMat; this.connectedTrans = connectedTrans; Rigidbody sourceBody = GetNonKinematicRigidbodyInParent(transform); Rigidbody connectedBody = GetNonKinematicRigidbodyInParent(connectedTrans); ropeJoint = sourceBody.gameObject.AddComponent <ConfigurableJoint>(); ropeJoint.autoConfigureConnectedAnchor = false; //ropeJoint.anchor = sourceBody.transform.InverseTransformPoint(transform.position); ropeJoint.anchor = Vector3.zero; if (connectedBody) { ropeJoint.connectedBody = connectedBody; //ropeJoint.connectedAnchor = connectedBody.transform.InverseTransformPoint(connectedTrans.position); ropeJoint.connectedAnchor = Vector3.zero; } else { /* Assume that this is a stationary transform */ ropeJoint.connectedAnchor = connectedTrans.position; } ropeJoint.xMotion = ConfigurableJointMotion.Limited; ropeJoint.yMotion = ConfigurableJointMotion.Limited; ropeJoint.zMotion = ConfigurableJointMotion.Limited; RestLength = distance; }
/*private void AdjustCollisions() * { * // Loop rope nodes and check if currently colliding * for (int i = 0; i < TotalNodes - 1; i++) * { * VerletRopeNode node = this.RopeNodes[i]; * * int result = -1; * result = Physics2D.OverlapCircleNonAlloc(node.transform.position, node.transform.localScale.x / 2f, ColliderHitBuffer); * * if (result > 0) * { * for (int n = 0; n < result; n++) * { * if (ColliderHitBuffer[n].gameObject.layer != 8) * { * // Adjust the rope node position to be outside collision * Vector3 collidercenter = ColliderHitBuffer[n].transform.position; * Vector3 collisionDirection = node.transform.position - collidercenter; * * Vector3 hitPos = collidercenter + collisionDirection.normalized * ((ColliderHitBuffer[n].transform.localScale.x / 2f) + (node.transform.localScale.x / 2f)); * node.transform.position = hitPos; * break; * } * } * } * } * }*/ private void ApplyConstraint() { // Apply start and end anchors if (nodeStartAnchor) { RopeNodes[0].transform.position = nodeStartAnchor.position; } if (nodeEndAnchor) { RopeNodes[TotalNodes - 1].transform.position = nodeEndAnchor.position; } for (int i = 0; i < TotalNodes - 1; i++) { VerletRopeNode node1 = this.RopeNodes[i]; VerletRopeNode node2 = this.RopeNodes[i + 1]; // Get the current distance between rope nodes float currentDistance = (node1.transform.position - node2.transform.position).magnitude; float difference = Mathf.Abs(currentDistance - NodeDistance); Vector2 direction = Vector2.zero; // determine what direction we need to adjust our nodes if (currentDistance > NodeDistance) { direction = (node1.transform.position - node2.transform.position).normalized; } else if (currentDistance < NodeDistance) { direction = (node2.transform.position - node1.transform.position).normalized; } // calculate the movement vector Vector3 movement = direction * difference; // apply correction node1.transform.position -= (movement * 0.5f); node2.transform.position += (movement * 0.5f); } }