2D Jumping Animation stuck on loop - c#

I have added the jumping animation to my player. When my player jumps, the animation plays. However when the player lands, the jump animation becomes stuck. When I check the animator tab, the jump animation is just being played on a loop.
This is the Code for the Jumping stuff - Animation/actual movement:
void Update()
{
horizontal = Input.GetAxisRaw("Horizontal");
animator.SetFloat("Speed", Mathf.Abs(horizontal));
if (Input.GetButtonDown("Jump") && IsGrounded())
{
rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
jump = true;
animator.SetBool("isJumping", true);
}
if (Input.GetButtonUp("Jump") && rb.velocity.y > 0f)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
}
if (Input.GetButtonUp("Jump") && IsGrounded())
{
animator.SetBool("isJumping", false);
animator.SetBool("isGrounded", true);
jump = false;
}
Flip();
}
This should check whether the player is grounded or not:
private bool IsGrounded()
{
return Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
}

This statement does not what you think it does
if (Input.GetButtonUp("Jump") && IsGrounded())
GetButtonUp returns true the first frame the button is released (see docs).
But it will return false again if the button has been released. This is not made that clear in the docs. Or to put it in other words: GetButtonUp returns true in that frame where the button has been released but in the frame before it was still pressed.
You could just detect the moment the player lands to switch animations:
if (jump && IsGrounded()) { // player just landed
animator.SetBool("isJumping", false);
animator.SetBool("isGrounded", true);
jump = false;
}

Related

Why does mashing jump let the player jump twice?

I'm having an issue where if the player mashes the jump button fast enough, they get an extra jump.
I'm pretty sure it has to do with my implementation of coyote time since it's letting the player jump even when slightly off the ground, but I'm not sure how I could change it to fix this issue without removing the mechanic entirely.
Here's the code I'm using for jumping.
//Check if player is grounded
IsGrounded = Physics2D.OverlapCircle(GroundCheck.position, 0.1f, GroundLayer);
//Coyote Jump
if (IsGrounded == true)
{
HangCount = HangTime;
}
else if(IsGrounded == false)
{
HangCount -= Time.deltaTime;
}
//Jump Buffer
if (Input.GetButtonDown("Jump"))
{
JumpBufferCount = JumpBufferLength;
}
else
{
JumpBufferCount -= Time.deltaTime;
}
//Jump
if (JumpBufferCount >= 0 && HangCount > 0)
{
RB.velocity = new Vector2(RB.velocity.x, JumpHeight);
FindObjectOfType<AudioManager>().Play("Jump");
HangCount = 0;
JumpBufferCount = 0;
}
}
}
Found a solution. I just added a check to see if my Y velocity was equal to or less than 0 so the player couldn't jump while already ascending.

player doesnt flip after animations are added

animator image
so im new in unity and im trynig to make my first game. so i made a code for flipping the player and it worked good, but when i added animations to the player it just stopped working! here is everything in my code relatable to the topic:
public bool facingLeft = false;
void flip()
{
facingLeft = !facingLeft;
facingRight = !facingRight;
Vector3 Scaler = transform.localScale;
Scaler.x *= -1;
transform.localScale = Scaler;
}
void FixedUpdate()
{
if (facingLeft == true && moveInput < 0)
{
flip();
}
if (facingRight == true && moveInput > 0)
{
flip();
}
}
pls help, thx
This is because you do define your animator but dont use it in the flip, you could or make it so that in the animation that the player moves and rotates accordingly to your stuff. like set the animation position itself.

Unity Rigidbody is sliding after jumping

I would like my character to jump diagonally but when it hits the ground it slides.
private void Update()
{
if (Input.GetMouseButtonUp(0) && isGrounded())
{
//jump
timeHeld = 0;
Debug.Log("MouseButtonUp = true");
rb.AddForce(jumpDirection, ForceMode2D.Impulse);
}
else if (isGrounded())
{
rb.velocity = Vector2.zero;
}
}
this code somehow works but it glitches when the player hits the ground. I need to put some amount of force to get him out of isGrounded() or he will just get some pixels up and be instantly pushed down again.
This is my isGrounded() function
private bool isGrounded()
{
RaycastHit2D raycastHit = Physics2D.BoxCast(boxCollider2d.bounds.center, boxCollider2d.bounds.size, 0f, Vector2.down, 0.1f, platformLayerMask);
return raycastHit.collider != null;
}
the problem is obviously my distance which is 0.1f in Boxcast(). Any ideas how to fix that?
No need to check the ground by yourself.
Add a unity event called OnCollisionEnter
Inside, check if the collider is the ground
If true, then velocity = zero

How unity raycast prevent double jump problem

I am trying to prevent the player to double jump, for that I am using Raycast to check if the player is in the layer Floor. My solution works sometimes, but sometimes it allows the player to double jump.
This is my code:
void Movement()
{
float movement = Input.GetAxis("Horizontal");
Vector3 playerVelocity = new Vector3(movement*speed, myRigidbody.velocity.y, speed);
myRigidbody.velocity = playerVelocity;
if (Input.GetKeyDown("space") && isGrounded)
{
Vector3 jumpVelocity = new Vector3(0f, jumpSpeed, 0f);
myRigidbody.velocity += jumpVelocity;
isGrounded = false;
Debug.Log("floor:"+isGrounded);
anim.SetInteger("AnimationPar", 3);
myAudioSource.Stop();
AudioSource.PlayClipAtPoint(jumpSound,transform.position, volumeSoundEffects);
}
else if (isGrounded && !myAudioSource.isPlaying && !levelFinished)
{
myAudioSource.Play();
}
if (!isGrounded)
{
IsGrounded();
}
}
void IsGrounded()
{
RaycastHit hit;
int mask = 1 << LayerMask.NameToLayer("Floor");
if (Physics.Raycast(transform.position, Vector3.down, out hit, 0.01f, mask))
{
//Debug.Log("Is touching floor");
isGrounded = true;
Debug.Log("floot:" + isGrounded);
anim.SetInteger("AnimationPar", 1);
if (!myAudioSource.isPlaying)
{
myAudioSource.Play();
}
}
}
The Movement method is called in Update. I think that maybe the IsGrounded method is called to fast and the player is still to close to the floor.
An easy way to prevent double jump is using a counter instead of raycast, it really makes everything easy. put a counter in this portion of the code:
if (Input.GetKeyDown("space") && isGrounded && counter <2)
{
Vector3 jumpVelocity = new Vector3(0f, jumpSpeed, 0f);
counter++;
Im unable to debug your code at this time, but another way you could do it is using OnCollisionEnter and OnCollisionExit
You can detect all things your players collides with, if one of them is the Floor then its likely hes grounded. But it would be possible to touch the floor on the side of the player while falling, to avoid this use the grounded method agian. You said it does work but sometimes fails. So try something like:
void OnCollisionEnter (Collision col)
{
if(col.gameobject.layer == LayerMask.NameToLayer("Floor") && IsGrounded())
{
isGrounded = true;
}
}
void OnCollisionExit (Collision col)
{
if(col.gameobject.layer == LayerMask.NameToLayer("Floor") && !IsGrounded())
{
isGrounded = false;
}
}
Thats untested code so im not 100% sure if it will work. The Exit may not work since IsGrounded may still be able to raycast to the ground. But if you handle your layers/collision in your levels right then you can remove the IsGrounded calls entirely.
This isnt the perfect solution by far but it might work.

Object not orienting correctly

I have a small script that causes an object to bounce back and forth. It is a bird for an upwards scrolling endless runner. So it represents its flight path. This script moves it from one end to the other and when it reaches the end it flips the 2D sprite and travels in the opposite direction. It works most of the time. But the problem is that sometimes the image flips twice so now it looks like its flying backwards until it does it again. Each time it does it it appears to be random.
public class Fly : MonoBehaviour {
private bool dirRight = false;
public float speed;
public bool facingRight = false;
void Start (){
speed = Random.Range (15.0f, 22.0f);
}
void Update () {
if(transform.position.x >= 25.0f) {
dirRight = false;
Flip();
}
if(transform.position.x <= -25.0f) {
dirRight = true;
Flip();
}
if (dirRight)
transform.Translate (Vector2.right * speed * Time.deltaTime);
else
transform.Translate (-Vector2.right * speed * Time.deltaTime);
}
void Flip()
{
// Switch the way the player is labelled as facing
facingRight = !facingRight;
// Multiply the player's x local scale by -1
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
I modified the if statements and use my bools as well as the position as such:
if(transform.position.x >= 25.0f && dirRight == true) {
dirRight = false;
Flip();
}
if(transform.position.x <= -25.0f && dirRight == false) {
dirRight = true;
Flip();
}
I am running it now and waiting to see if it works.
you are calling Flip() method based on position. and position is updated per frame. So it takes time to Lerp from >=25 to <25 so in every frame when position is >= 25 or <= -25 it calls to Flip(). So you need to add another check for calling Flip(). May be facingright == true will work.

Categories