Remake of the game Cut The Rope for the purpose of learning the Unity video game development platform at the 3W Academy training school.


Generation of ropes and their Hinge Joint 2D

The pin and ropes

In the Awake method, the ropes attached to the pine are generated on the fly.

These ropes are created from sprites and each have a Hinge Joint 2D that connects them together.
Hierarchy
The Hinge Joint 2D component allows a GameObject  controlled by RigidBody  2D physics to be attached to a point in space around which it can rotate.

Here is the GenerateRopes class below which generates the strings and links.

To obtain a graphic and animated rendering as beautiful as the original game, it is necessary to use the Line Renderers which allow to have a more natural and less "broken" rendering, but the code to be created is heavier and is not discussed here.
public class GenerateRopes : MonoBehaviour
{
    [SerializeField] private Transform _rope;
    [SerializeField] private Transform _candy;
    [SerializeField] private int _ropesNumber;
    private Transform[] _ropesArray;
    private Transform _transform;
    private void Awake()
    {
        _transform = GetComponent<transform>();

        // Instantiate ropes given in parameters
        _ropesArray = new Transform[_ropesNumber];

        for (int i = 0; i < _ropesNumber; i++)
        {
            _ropesArray[i] = Instantiate(_rope, Vector2.zero, Quaternion.identity);
            _ropesArray[i].gameObject.SetActive(true);

            // Storage of the ropes in their parent pine
            _ropesArray[i].transform.parent = gameObject.transform;
            if (i == 0)
            {
                // Link the first instantiated rope to the Pin
                _transform.GetComponent<hingejoint2d>().connectedBody = _ropesArray[0].GetComponent<rigidbody2d>();
            }
            else
            {
                // Link with the following rope
                _ropesArray[i - 1].GetComponent<hingejoint2d>().connectedBody = _ropesArray[i].GetComponent<rigidbody2d>();
            }
        }
        // Link the last intantiated rope to the candy
        _ropesArray[_ropesNumber - 1].GetComponent<hingejoint2d>().connectedBody = _candy.GetComponent<rigidbody2d>();
    }
}


Cut of the rope and trail renderer effects

Trail Renderer componant

We have to create a GameObject containing the Trail Renderer componant and the script (bellow).

We need to use a Raycast to detect the collision. BUT, if the mouse moving to fast, the raycast will NOT hit the rope!

So, to get better accuracy, we need to draw a raycast between mouse position from the last frame to the current frame.

The distance is calculated from the substraction of target vector minus origin vector.

And then, the CuteTheRope() method just tests the ropes colliders, and if it returns true, the rope is inactivated.
It is safer to deactivate first and then destroy the object when you know that there is no longer any interaction around it.
Another solution: instead of deactivating a rope, we could also have removed a Hinge Joint 2D.
private void Update()
{
    if (Application.platform == RuntimePlatform.Android)
    {
        // [...] The source code is almost identical, we focus on the web version below ;-)
    }
    else
    {
        if (Input.GetMouseButton(0))
        {
            mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

            // Trail renderer effect position on _transform (the current gameObject that contains this script)
            _transform.position = mouseWorldPos;

            // Calculate the direction of the vector between last frame and current frame.
            Vector2 dir = (mouseWorldPos - mouseWorldLastPos).normalized;
            float dist = Vector2.Distance(mouseWorldPos, mouseWorldLastPos);
            Debug.DrawRay(mouseWorldPos, dir, Color.red);

            // We must do a raycast between the previous frame and the current frame.
            // This is necessary because if we move the mouse too fast, the cut of the string
            // will pass between two frames and will not be affected by the raycast!
            _hit = Physics2D.Raycast(mouseWorldPos, dir, dist);
            CuteTheRope();
            mouseWorldLastPos = mouseWorldPos;
        }
        else
        {
            mouseWorldLastPos = Vector2.zero;
        }
    }
}
private void CuteTheRope()
{
    if (_hit.collider != null
        && _hit.collider.tag == "Rope")
    {
        // Remove the portion of the hit rope.
        _hit.collider.gameObject.SetActive(false);
    }
}

Game originally created in 2010 by ZeptpLab, a Russian company. This game has been downloaded more than 405 million times since its release!

Download

Download
Cute_the_Rope.apk 32 MB

Comments

Log in with itch.io to leave a comment.

epic