- Home /
Freezing Z axis makes my character stick to walls
Hello there,
I'm new to Unity and C#. I was just playing aroung with a simple square scene trying to get smooth controls of it, aka a nice jump, wall sliding and wall jumping, kind of in the Super Meat Boy way. It works ok, but sometimes after a lot of collisions on walls (which are simple vertical rectangles) the cube rotates on its axis. I tried to fix it by freezing the Z axis, but when I do, the cube sometimes sticks to the walls, despite the "wall sliding" part I added (decreasing the horizontal movement if the player inputs movement in direction of the wall) that works good when the Z axis is not frozen.
Could somebody please explain me what happens here, and possibly give me hints on how to fix it? Any help would be appreciated. Also, if some parts of the code seem irrelevant/depreciated/unoptimized, feel free to tell me so I can improve.
Thanks a lot.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[Range(1, 10)]
public float speed;
[Range(1, 10)]
public float jumpForce;
[Range(1, 10)]
public float fallGravity;
[Range(1, 10)]
public float lowJumpGravity;
bool isOnGround;
bool isOnWall;
bool isJumping;
float horizontalMovement;
Rigidbody2D rbody;
void Awake()
{
// Application.targetFrameRate = 60;
rbody = GetComponent<Rigidbody2D>();
isOnGround = true;
isOnWall = false;
isJumping = false;
}
void FixedUpdate()
{
horizontalMovement = Input.GetAxisRaw("Horizontal");
isJumping = (Input.GetButton("Jump"));
/* -------------------- MOVEMENT CONTROLS -------------------- */
/* --- GROUND MOVEMENT --- */
// Horizontal movement
if (!Mathf.Approximately(horizontalMovement, 0.0f))
rbody.velocity = new Vector2(horizontalMovement * speed, rbody.velocity.y); // adds X velocity
// Jump
if (isJumping && isOnGround)
rbody.velocity = Vector2.up * jumpForce; // adds Y velocity
/* --- AIR MOVEMENT --- */
if (!isOnGround)
{
// improved falling
if (rbody.velocity.y < 0)
rbody.velocity += Vector2.up * Physics2D.gravity.y * (fallGravity - 1) * Time.deltaTime; // adds more Y gravity with the fallGravity coefficient
else if (rbody.velocity.y > 0 && !isJumping) // else if the player is not falling but released the jump button (for a low jump)
rbody.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpGravity - 1) * Time.deltaTime; // adds more Y gravity with the lowJumpGravity coefficient
/* --- WALL MOVEMENT --- */
if (isOnWall)
{
// raycast to check if the wall is on the right
RaycastHit2D hitRight = Physics2D.Raycast(rbody.position, Vector2.right, GetComponent<SpriteRenderer>().bounds.size.x + 1, LayerMask.GetMask("Environment"));
if (hitRight.collider != null)
{
// if the player moves right
if (horizontalMovement > 0.0f)
{
// Wall sliding - slowing the horizontal speed
rbody.velocity = new Vector2(speed / 5f, rbody.velocity.y);
// if the player tries to jump in the direction of the wall
if (isJumping)
rbody.velocity = new Vector2(-1, 1) * new Vector2(jumpForce * 5f, jumpForce);
}
// if the player moves left
else if (horizontalMovement < 0.0f)
{
if (isJumping)
rbody.velocity = new Vector2(-1, 1) * new Vector2(jumpForce, jumpForce);
}
}
// raycast to check if the wall is on the left
RaycastHit2D hitLeft = Physics2D.Raycast(rbody.position, Vector2.left, GetComponent<SpriteRenderer>().bounds.size.x + 1, LayerMask.GetMask("Environment"));
if (hitLeft.collider != null)
{
// if the player moves left
if (horizontalMovement < 0.0f)
{
// Wall sliding - slowing the horizontal speed
rbody.velocity = new Vector2(speed / 5f, rbody.velocity.y);
// if the player tries to jump in the direction of the wall
if (isJumping)
rbody.velocity = new Vector2(1, 1) * new Vector2(jumpForce * 5f, jumpForce);
}
// if the player moves right
else if (horizontalMovement > 0.0f)
{
if (isJumping)
rbody.velocity = new Vector2(1, 1) * new Vector2(jumpForce, jumpForce);
}
}
}
}
/* -------------------- XXXXXXXXXX -------------------- */
}
void OnCollisionEnter2D(Collision2D collidingObject)
{
if (collidingObject.gameObject.tag == "Ground")
isOnGround = true;
if (collidingObject.gameObject.tag == "Wall")
{
isOnWall = true;
}
}
void OnCollisionExit2D(Collision2D collidingObject)
{
if (collidingObject.gameObject.tag == "Ground")
isOnGround = false;
if (collidingObject.gameObject.tag == "Wall")
isOnWall = false;
}
}
Your answer
Follow this Question
Related Questions
How to make enemy walk on walls, while go toward player? 6 Answers
2d player can get stuck in walls if you hold down (Not the physics material fixable glitch) 0 Answers
Rigidbody Sticks to Walls 3 Answers
Importing from Maya 2 Answers
New User, New Project 0 Answers