Creating sticks and ropes in Unity

Rope or rope like objects can be found in many places in game. Cable lines between poles, vines hanging from trees or spiders swinging by web othey all have similar kind of behavior. We are going to create that and see how it can be used in game.

Rope or rope like objects can be found in many places in game. Cable lines between poles, vines hanging from trees or spiders swinging by web othey all have similar kind of behavior. We are going to create that and see how it can be used in game.

The rope we are going to create will two components. Vertices and line. We will call them Node and Stick. A Stick will have two Nodes connected to it making link between them. Node will be responsible for simulating movements, maintaining structure of rope and handling physics. There will also be fixed nodes that will not move and will act as attached point for rope. Stick will act as constraints between two nodes keeping them within certain distance.

Creating a Node

As Node is responsible for movement, let's first create a method to move it. In our Node class define move function that will move it.

    void Move(Vector3 moveVector) {
      //get movement vector and translate it with that vector
      transform.Translate(moveVector);
    }

Movement of vertices will be done from FixedUpdate. We will be calculating it's velocity using position in previous frame and add gravity to it. It will make our node react to gravity making it fall freely.

    public bool isFixed; //if true this point will not be affected by gravity or stick constraint and act as connected point for rope
    public static float gravity = -9.8 f; //value of gravity to calculate the rate at which object falls
    public Vector2 previousPosition; //position of vertices in previous update. It will be used to calculate velocity in next frame

    //We are not directly using FixedUpdate here because order of updating is importaint. 
    //So just create a method for now which will be updated from other place
    public void UpdateNode() {
      if (isFixed) return; //dont move if fixed point

      Vector2 velocity = (Vector2) transform.position - previousPosition;
      calculate velocity to preserve momentum
      previousPosition = transform.position; //save current position to be used in next update

      //add acceleration
      velocity += Vector2.up * gravity * Time.fixedDeltaTime * Time.fixedDeltaTime;

      //move object
      Move(velocity);
    }
Node falling with gravity

Creating a Stick

We will be using LineRenderer to make a stick. It will have two nodes that will be connected and a length parameter that will define constraints for the distance between two nodes.

First, let's create a method to make a line between two nodes

    private LineRenderer lineRenderer;

    private void UpdateLineRenderer() {
      lineRenderer.SetPositions(new [] {
        node1.transform.position,
          node2.transform.position
      });
    }

Now, we need to create a UpdateStick method for handling constraints between nodes. This will just move nodes towards each other if their distance is larger than length

    public float length;

    public void UpdateStick() {
      Vector2 center = (node1.transform.position + node2.transform.position) / 2; //calculate midpoint betwen node

      if (!node1.isFixed) {
        Vector2 node1DirTowardCenter = ((Vector2) node1.transform.position - center).normalized; //calculate direction towards center point
        node1.transform.position = node1DirTowardCenter * length / 2 + center; //move point at the right distance i.e half the length from center

      }

      if (!node2.isFixed) {
        //do same for another node
        Vector2 node2DirTowardCenter = ((Vector2) node2.transform.position - center).normalized;
        node2.transform.position = node2DirTowardCenter * length / 2 + center;
      }

      //make a line between two node after updating node position is completed
      UpdateLineRenderer();
    }

Now we need to initialize lineRenderer and calculate position at Awake

    private void Awake() {
      lineRenderer = GetComponent < LineRenderer > ();
      lineRenderer.useWorldSpace = true;
      length = Vector2.Distance(node1.transform.position, node2.transform.position); //calculate distance between nodes at begining. we will be using it to maintain distance throughout simulation

      UpdateLineRenderer(); //update line renderer to connect two points
    }
Nodes after being connected by stick

Creating a Rope

Finally, we will create a Rope class that will update each vertice and stick. Updates will happen in FixedUpdate method as it will give a consistent result.

public class Rope: MonoBehaviour {
  public Node[] nodes; //collection for nodes in scene

  public Stick[] sticks; //collection for sticks in scene

  private void Awake() {
    //find all nodes and sticks in scene
    nodes = FindObjectsOfType < Node > ();
    sticks = FindObjectsOfType < Stick > ();
  }

  void FixedUpdate() {
    //update nodes at first
    foreach(Node node in nodes) {
      node.UpdateNode();
    }

    for (int i = 0; i < 3; i++) {
      //we may want to update sticks multiple times because one node will be updated by multipe sticks.
      //doing multiple iteration will give precise result but single iteration is enough for simpler games

      //update sticks to maintain distance between nodes
      foreach(Stick stick in sticks) {
        //update only if gameobject is active
        if (stick.gameObject.activeSelf)
          stick.UpdateStick();
      }
    }
  }
}

Setting up in Unity editor

Create a GameObject for Node and Stick in the scene and add respective scripts to it.Stick should have LineRenderer attached to it. Connect the  required Nodes in node1 and node2 of stick. Finally, add Rope script in scene and we are good to go.

Also, we can enable or disable Stick object to get cutting and joining effect of rope.

Further improvements and customization

This is a really basic and simple system to make rope-like objects. Using only this will not be enough for a good game. So, what else to add to it? Well, there are many. You can add wind effect along with gravity in node. Or add collider in vertices so that it will interact with other physical objects. Also, another interesting thing to do is make a playable character that can grab/release a Node and swing like a monkey swinging from rope to rope. Basic cloth simulation can also be done by arranging Node in the grid and connecting four nodes around it with Stick. There are just so many possibilities.

Thank you for reading. If you have any question or suggestion please comment below.