Search Unity

String Following Player Effect

Discussion in '2D' started by unitynoob24, Jul 22, 2016.

  1. unitynoob24

    unitynoob24

    Joined:
    Dec 27, 2014
    Posts:
    398
    Hey guys!

    I am looking to have my player bound to a string essentially, with some elasticity and am not quite sure how to go about achieving this. I was thinking some kind of hinge joint but I am not 100% sure.

    Basically the player can move anywhere they want stretching out the string, but when they are not moving they will snap back to the strings origin. So when they move, the string will stretch out with them.

    Thanks guys!
     
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
  3. unitynoob24

    unitynoob24

    Joined:
    Dec 27, 2014
    Posts:
    398
    The character is already moving with AddForce, but I have never heard of a spring joint.. hm.. Thanks so much! Checking out the docs now!

    EDIT:

    Okay so this looks like it may be what I am looking to do!

    The next step is making this something visual on the screen? How would I have say, a rubbery rope for example, like a vector that stretches with the joint?
     
    Last edited: Jul 22, 2016
  4. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    If you have a rope sprite, in the sprite editor you can set the pivot to be the very end and center of it.

    Then you can set its position to one end of the spring joint, and each frame update its scale and rotation to stretch it to the other point. I wrote a script to do that previously, so see if this works for you:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class StretchToEndPoint : MonoBehaviour {
    4.  
    5.     [Tooltip("The point to stretch to.")]
    6.     public Transform endPoint;
    7.  
    8.     [Tooltip("If true, will rotate and stretch the X Axis, otherwise Y Axis.")]
    9.     public bool useXAxis;
    10.  
    11.     [Tooltip("If true, will use the negative axis instead of positive.")]
    12.     public bool negativeAxis;
    13.  
    14.     private SpriteRenderer mySpriteRenderer;
    15.     private float currentDistance;
    16.     private Vector2 spriteSize;
    17.  
    18.     private void Awake() {
    19.         mySpriteRenderer = GetComponent<SpriteRenderer>();
    20.         spriteSize = mySpriteRenderer.sprite.bounds.size;
    21.     }
    22.  
    23.     private void Update() {
    24.         UpdateRotation();
    25.         UpdateScale();
    26.     }
    27.  
    28.     private void UpdateRotation() {
    29.         // get the vector between this object and the endPoint
    30.         Vector3 difference = endPoint.position - transform.position;
    31.  
    32.         // get the length of that vector
    33.         currentDistance = difference.magnitude;
    34.  
    35.         // point the Z axis forwards, and the Y axis in the direction of the endpoint.
    36.         Quaternion newRotation = Quaternion.LookRotation(Vector3.forward, difference.normalized);
    37.  
    38.         if(useXAxis) {
    39.             // rotate an extra 90 degrees to point the X axis instead of Y
    40.             newRotation *= Quaternion.Euler(0, 0, 90);
    41.         }
    42.  
    43.         // apply the new rotation
    44.         transform.rotation = newRotation;
    45.     }
    46.  
    47.     private void UpdateScale() {
    48.         // get the correct sprite dimension
    49.         float spriteLength = useXAxis ? spriteSize.x : spriteSize.y;
    50.  
    51.         // divide the distance to stretch by the length of the sprite
    52.         // ( this is what the scale needs to be to reach the endPoint )
    53.         float newAxisScale = currentDistance / spriteLength;
    54.  
    55.         // make sure the scale is negative if necessary
    56.         if(negativeAxis && newAxisScale > 0) {
    57.             newAxisScale *= -1;
    58.         }
    59.  
    60.         Vector3 newScale = Vector3.one;
    61.  
    62.         // alter the proper axis' scale
    63.         if(useXAxis) {
    64.             newScale.x = newAxisScale;
    65.         } else {
    66.             newScale.y = newAxisScale;
    67.         }
    68.  
    69.         // apply the scale
    70.         transform.localScale = newScale;
    71.     }
    72. }