I’m making a grappling hook with a distance joint in my 2D platformer game. However, the player is supposed to swing fast when they hook onto an object, but instead, they are swinging slowly.
I tried creating another sprite and adding the same Grappling Hook script to it. When I pressed play, the sprite swung fast as intended. The player’s and the sprite’s components, such as Rigidbody, distance joint, and line renderer, are the same, except I didn’t include the PlayerController script in the other sprite. Therefore, I think something is wrong with my PlayerController script that prevents the player from swinging fast, because I removed PlayerController script from the player and It worked, but PlayerController script is very useful.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class PlayerMovement : MonoBehaviour
{
// Status
[Header("Status")]
[SerializeField] public float hp;
[SerializeField] private int hearts;
[SerializeField] public float speed;
[SerializeField] public float regularSpeed;
[SerializeField] private float jumpForce;
// Movement Mechanics
[Header("Movement Mechanics")]
public Rigidbody2D rb;
private float move;
[SerializeField] private bool isOnGround;
[SerializeField] private Transform groundCheck;
[SerializeField] private LayerMask groundLayer;
[SerializeField] private bool isMovingLeft;
[SerializeField] private bool isMovingRight;
public bool canMove;
// Attack Mechanics
[Header("Attack Mechanics")]
public float shootDmg;
[SerializeField] private float attackDmg;
[SerializeField] private Transform shootingPoint;
[SerializeField] private GameObject bullet;
// Raycast
[Header("Raycast")]
[SerializeField] private float obstacleRayDistance;
[SerializeField] private GameObject obstacleRayObject;
// UI
[Header("UI")]
public Slider healthBar;
public TMP_Text heartsCount;
void Start()
{
rb = GetComponent<Rigidbody2D>();
speed = regularSpeed;
}
void Update()
{
// Health
if (hp <= 0)
{
Death();
}
healthBar.value = hp;
heartsCount.text = hearts.ToString();
if (!canMove)
{
Debug.Log("You can't move");
return;
}
// Check for keyboard inputs
if (Input.GetKey(KeyCode.A))
{
MoveLeft();
}
else if (Input.GetKey(KeyCode.D))
{
MoveRight();
}
else if (!isMovingLeft && !isMovingRight)
{
StopMoving();
}
// Set direction based on button states
if (isMovingLeft)
{
MoveLeft();
}
else if (isMovingRight)
{
MoveRight();
}
// Jump when the Jump button is pressed and player is grounded
if (Input.GetButtonDown("Jump") && isGrounded() && canMove)
{
rb.AddForce(new Vector2(rb.velocity.x, jumpForce));
}
if (Input.GetButtonUp("Jump") && rb.velocity.y > 10)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
}
// Shooting function (commented out)
// if(Input.GetButtonDown("Shoot") && canMove)
// {
// Instantiate(bullet, shootingPoint.position, transform.rotation);
// }
}
void FixedUpdate()
{
// Update Rigidbody velocity based on move direction
rb.velocity = new Vector3(speed * move, rb.velocity.y, 0);
}
// Button press handlers
public void OnLeftButtonDown() => isMovingLeft = true;
public void OnLeftButtonUp() => isMovingLeft = false;
public void OnRightButtonDown() => isMovingRight = true;
public void OnRightButtonUp() => isMovingRight = false;
public void MoveLeft()
{
transform.eulerAngles = new Vector3(0, 180, 0);
move = -1;
}
public void MoveRight()
{
transform.eulerAngles = new Vector3(0, 0, 0);
move = 1;
}
public void Jump()
{
if (isGrounded() && canMove)
{
rb.AddForce(new Vector2(rb.velocity.x, jumpForce));
}
}
public void StopMoving()
{
move = 0;
}
private bool isGrounded()
{
return Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
}
public void Death()
{
hp = 100f;
hearts -= 1;
}
}
Grappler script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Grappler : MonoBehaviour
{
public Camera mainCamera;
public LineRenderer _lineRenderer;
public DistanceJoint2D _distanceJoint;
public GameObject[] grapplingObjects;
public GameObject nearestObject;
float distance;
float nearestDistance = 10000;
// Start is called before the first frame update
void Start()
{
grapplingObjects = GameObject.FindGameObjectsWithTag("GrapplingObject");
_distanceJoint.enabled = false;
}
// Update is called once per frame
void Update()
{
for (int i = 0; i < grapplingObjects.Length; i++)
{
distance = Vector2.Distance(this.transform.position, grapplingObjects[i].transform.position);
if(distance < nearestDistance)
{
nearestObject = grapplingObjects[i];
nearestDistance = distance;
}
}
if (Input.GetKeyDown(KeyCode.Mouse0))
{
Vector2 mousePos = (Vector2)mainCamera.ScreenToWorldPoint(Input.mousePosition);
_lineRenderer.SetPosition(0, nearestObject.transform.position);
_lineRenderer.SetPosition(1, transform.position);
_distanceJoint.connectedAnchor = nearestObject.transform.position;
_distanceJoint.enabled = true;
_lineRenderer.enabled = true;
}
else if (Input.GetKeyUp(KeyCode.Mouse0))
{
_distanceJoint.enabled = false;
_lineRenderer.enabled = false;
}
if (_distanceJoint.enabled)
{
_lineRenderer.SetPosition(1, transform.position);
}
}
}
Here’s the video of player:
https://youtu.be/LKtuEjaY_KM
And here’s the video of another sprite:
https://youtube.com/shorts/CguW2uXhBv8?feature=share