- Home /
Question by
fxlix1 · Apr 20 at 01:07 PM ·
2d-platformer2d-physicstargetjoint2dmovement
2D Grappling Hook problems
Hello, I'm making a 2D platformer game and I wanted to add a grappling hook with a target-joint (or a spring joint) but the grappling hook doesn't work with my movement script. When I'm grappling, the player doesn't move directly to my target. When I disable the movement script on my player the grappling hook works as it should.
PlayerMovement:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private Rigidbody2D rb;
private SpriteRenderer sR;
public Transform sprites;
public Transform groundCheckOne;
public Transform groundCheckTwo;
public LayerMask whatIsGround;
public float speed;
public float jumpForce;
private float moveInput;
public float checkRadius;
private int extraJumps;
public int extraJumpsValue;
private bool facingRight = true;
public bool isGrounded;
public float groundWalkTime;
private float walkTime;
// wallsliding variables
private bool wallsliding;
public bool isTouchingFront;
public Transform frontCheck;
public float wallSlidingSpeed;
// walljumping variables
public float wallJumpTime;
private float jumpTime;
void Awake(){
rb = GetComponent<Rigidbody2D>();
sR = GetComponent<SpriteRenderer>();
}
void Start()
{
extraJumps = extraJumpsValue;
}
void FixedUpdate()
{
Movement();
}
void Update(){
GroundCheck();
Wallsliding();
Jump();
}
// Movement
void Movement(){
// Basic Movement
moveInput = Input.GetAxis("Horizontal");
rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
// Check the facing direction
if(facingRight == false && moveInput > 0){
Flip();
} else if(facingRight == true && moveInput < 0){
Flip();
}
}
// Jumping
void Jump(){
// Reset extra jumps when grounded or wallsliding
if(isGrounded == true){
extraJumps = extraJumpsValue;
}
if(wallsliding == true){
extraJumps = extraJumpsValue;
}
// Jumping
if((Input.GetKeyDown(KeyCode.Space) && (extraJumps > 0 || isGrounded)) && wallsliding == false){
rb.velocity = Vector2.up * jumpForce;
extraJumps--;
} else if (Input.GetKeyDown(KeyCode.Space) && wallsliding == true){
rb.velocity = Vector2.up * jumpForce;
}
}
// Wallsliding
void Wallsliding(){
// Checks if the Player hits the wall
isTouchingFront = Physics2D.OverlapCircle(frontCheck.position, checkRadius, whatIsGround);
if(isTouchingFront == true && isGrounded == false && moveInput != 0){
rb.velocity = new Vector2(rb.velocity.x, Mathf.Clamp(rb.velocity.y, -wallSlidingSpeed, float.MaxValue));
wallsliding = true;
jumpTime = Time.time + wallJumpTime;
} else if(jumpTime < Time.time){
wallsliding = false;
}
}
// Check if Player is grounded
void GroundCheck(){
// Checks if one groundcheck hits the ground
if(Physics2D.OverlapCircle(groundCheckOne.position, checkRadius, whatIsGround) || Physics2D.OverlapCircle(groundCheckTwo.position, checkRadius, whatIsGround)) {
isGrounded = true;
walkTime = Time.time + groundWalkTime;
}
// Checks if both groundchecks hit the ground
else if(Physics2D.OverlapCircle(groundCheckOne.position, checkRadius, whatIsGround) && Physics2D.OverlapCircle(groundCheckTwo.position, checkRadius, whatIsGround)) {
isGrounded = true;
walkTime = Time.time + groundWalkTime;
}
// If no groundcheck hit the ground and the time is over isGrounded = false
else if(walkTime < Time.time){
isGrounded = false;
}
}
// Flip the Player
void Flip(){
facingRight = !facingRight;
// Flip the eyes
Vector3 currentSpritesScale = sprites.transform.localScale;
currentSpritesScale.x *= -1;
sprites.transform.localScale = currentSpritesScale;
// Flip the bodysprite
sR.flipX = !sR.flipX;
// Change the frontCheck-position
Vector3 currentFrontCheckPosition = frontCheck.transform.localPosition;
currentFrontCheckPosition.x *= -1;
frontCheck.transform.localPosition = currentFrontCheckPosition;
}
}
Grappling Hook:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hook : MonoBehaviour
{
private TargetJoint2D targetJoint;
private Camera cam;
private Rigidbody2D rb;
public LayerMask whatIsGround;
public float distance;
private RaycastHit2D rayHit;
private Vector3 mousePos;
private Vector2 mousePos2;
private Vector2 transformPosition;
private Vector3 targetDirection;
private Vector2 targetPosition;
void Awake(){
targetJoint = GetComponent<TargetJoint2D>();
cam = Camera.main;
rb = GetComponent<Rigidbody2D>();
}
void Start(){
}
void Update(){
GetMousePosition();
if (Input.GetMouseButtonDown(0)){
GrappleOn();
}
if (Input.GetMouseButtonUp(0)){
GrappleOff();
}
}
void GrappleOn(){
transformPosition = transform.position;
targetDirection = (transformPosition - mousePos2) * -1;
// Check if the raycast hits the ground
rayHit = Physics2D.Raycast(transform.position, targetDirection, distance, whatIsGround);
Debug.DrawRay(transform.position, targetDirection, Color.blue);
if(rayHit){
// Set the targetposition to the rayhit
targetPosition = rayHit.point;
// Enable the targetJoint
targetJoint.enabled = true;
// Set the targetJoint-target to the targetposition
targetJoint.target = targetPosition;
}
}
void GrappleOff(){
targetJoint.enabled = false;
}
void GetMousePosition(){
mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = 0;
mousePos2 = mousePos;
}
}
,
EDIT: I have figured out that the bug is caused by this line in "Movement"
rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
screenshot-11-li.jpg
(444.3 kB)
screenshot-12-li.jpg
(370.0 kB)
Comment