Here’s my solution
Summary
One challenge is missing as was removed as it caused errors further down the line - pun intended
Code
using System.Collections;
using UnityEngine;
public class GrapplingHook : MonoBehaviour
{
[SerializeField] float playerSpeed = 1f;
[SerializeField] float ropeSpeed = 5f;
[SerializeField] private float distance = 10f;
[SerializeField] private LayerMask mask;
[SerializeField] private LineRenderer line;
[SerializeField] private float grappleSpeed = 3f;
[SerializeField] private GameObject playerHand;
DistanceJoint2D joint;
Vector3 targetPos;
RaycastHit2D hit;
Rigidbody2D connectedRigidbody;
private void Start()
{
joint = GetComponent<DistanceJoint2D>();
joint.enabled = false;
line.enabled = false;
}
void Update()
{
PullPlayer();
if (Input.GetMouseButtonDown(0))
{
targetPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
targetPos.z = 0;
hit = Physics2D.Raycast(playerHand.transform.position, targetPos - playerHand.transform.position, distance, mask);
if (hit.collider != null && hit.collider.gameObject.GetComponent<Rigidbody2D>() != null)
{
joint.enabled = true;
connectedRigidbody = hit.collider.attachedRigidbody;
joint.connectedAnchor = hit.point;
joint.distance = Vector2.Distance(playerHand.transform.position, hit.point);
StartCoroutine(FireLine(hit.point));
}
}
if (Input.GetMouseButton(0))
{
line.SetPosition(0, playerHand.transform.position);
}
if (Input.GetMouseButtonUp(0))
{
joint.enabled = false;
line.enabled = false;
StopAllCoroutines();
}
}
IEnumerator FireLine(Vector2 point)
{
line.enabled = true;
float perc = 0;
while (perc < 1 && line.enabled)
{
perc += Time.deltaTime * ropeSpeed;
line.SetPosition(0, playerHand.transform.position);
line.SetPosition(1, Vector3.Lerp(playerHand.transform.position, point, perc));
yield return null;
}
if (line.enabled) line.SetPosition(1, point);
}
void PullPlayer()
{
if (!joint.enabled) return;
joint.distance -= Time.deltaTime * playerSpeed;
}
void OnCollisionEnter2D(Collision2D collision)
{
if (connectedRigidbody == collision.rigidbody)
{
joint.enabled = false;
line.enabled = false;
}
}
}