Example #1
0
    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;
    }
Example #2
0
    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;
    }
Example #3
0
    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;
    }
Example #4
0
    /*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);
        }
    }