- Home /
My flip animation will not play when double jumping
The simple version is that I am trying to make my character flip in midair using this code: using System.Collections; using System.Collections.Generic; using UnityEngine;
public class FlipController: MonoBehaviour { private int maxflips = 1; int flips; public bool ICanFlip; private Animator anim;
void Start()
{
anim = GetComponent<Animator>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Flip();
}
}
void Flip()
{
if (ICanFlip == true && flips > 0)
{
{
anim.Play("Ninja Flip");
flips = flips - 1;
}
}
if (ICanFlip == false)
{
return;
}
}
//leaves the ground
void OnCollisionEnter(Collision other)
{
if (other.gameObject.tag == "Grass")
{
ICanFlip = false;
flips = maxflips;
}
}
//in air
void OnCollisionExit(Collision other)
{
if (other.gameObject.tag == "Grass")
{
ICanFlip = true;
}
}
}
The character controller is the script here: using System.Collections; using System.Collections.Generic; using UnityEngine;
public class PlayerController : MonoBehaviour {
Rigidbody rb;
private int maxjumps = 2;
int jumps;
public float speed = 20f;
public float jumpHeight = 100f;
public bool isGrounded;
public bool inAir;
void Start()
{
rb = GetComponent<Rigidbody>();
rb.freezeRotation = true;
}
void Update()
{
//movement
if (Input.GetKey(KeyCode.D))
{
rb.AddForce(Vector3.right * speed);
}
if (Input.GetKey(KeyCode.A))
{
rb.AddForce(Vector3.left * speed);
}
if (Input.GetKeyDown(KeyCode.Space))
{
Jump();
}
}
void Jump()
{
//Jump from ground
if (jumps > 0)
{
rb.AddForce(Vector3.up * jumpHeight);
isGrounded = false;
jumps = jumps - 1;
}
if (jumps == 0)
{
return;
}
}
//leaves the ground
void OnCollisionEnter(Collision other)
{
if (other.gameObject.tag == "Ground")
{
jumps = maxjumps;
isGrounded = true;
inAir = false;
}
}
//in air
void OnCollisionExit(Collision other)
{
if (other.gameObject.tag == "Ground")
{
isGrounded = false;
inAir = true;
}
}
}
I'm sorry for not using many comments but it is pretty much self-explanatory.
The controls and double jumping works fine, but I cannot get the flip animation to work. The collisions are also not working. If you have any questions, feel free to ask. I'm pretty new to this.
The inAir bool in the playerController script is just for me to check if it's successfully updating. You can ignore it when answering.
Answer by SilverDarkwings · Sep 12, 2019 at 12:46 AM
I decided to simplify my code into
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FlipController : MonoBehaviour
{
private int maxflips = 2;
int flips;
private Animator anim;
void Start()
{
anim = GetComponent<Animator>();
flips = maxflips;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && flips > 1)
{
flips = flips - 1;
return;
}
if (Input.GetKeyDown(KeyCode.Space) && flips == 1)
{
Flip();
}
}
void Flip()
{
{
{
anim.Play("Ninja Flip");
flips = flips + 1;
}
}
}
}
It works pretty well. If you could help me out with adding a cool down, like 3 seconds before the code loops, that would be great.
Yeah that will work of course, but aren't you now losing the ability to detect when the player should be allowed to flip? i.e. now they can flip even when just stood on the ground (which it seemed like you did not want).
As for adding a timer, there will be loads of examples of that kind of thing online but if you get stuck then post another question on here
Yes, I do not have the ability to detect if my player should be allowed to flip but since I was trying to get my player to flip only on the second time and it was a success. I will have to work on the detection part another time since I am still a student and do not have much time. I would rather focus on creating the rest of the game itself ins$$anonymous$$d of getting stuck on one part but any help on that front would certainly be welcome. Thank you for your help lately.
To clarify on something i forgot to mention, The PlayerController script is on an empty gameObject with the actual Ninja gameObject under it. The FlipController script is attached to the Ninja gameObject. The empty gameObject has a rigidbody but the Ninja gameObject does not. This was why I could not use OnCollisionEnter successfuly.
Answer by a_flipen_default · Sep 10, 2019 at 02:32 PM
void Flip()
{
if (ICanFlip == true && flips > 0)
{
{
anim.Play("Ninja Flip");
*flips = flips - 1;*
}
}
if (ICanFlip == false)
{
return;
}
}
if flip = 0 minusing by 1 wil make if(flip > 0) inposible
I would rather use Raycast like:
if(Phiscis.Raycast(ray, vec.down, out raycasthit dist)) { if(dist < jumpHight) }
but look at the IF statement right above that part where it $$anonymous$$us 1 from flips.
It only gets to that part that $$anonymous$$us 1 from flips if flips is greater than 0. So you can never end up with flips = 0 and then $$anonymous$$us 1 from it
Answer by Chris128 · Sep 11, 2019 at 01:59 PM
It looks like you're relying on the OnCollisionEnter function to actually initialise your flips variable. Depending on how you've got your scene setup, maybe the character does not actually enter a collision with that "Grass" object that you're checking for so the flips variable is just staying at 0?
First thing I would do is make sure that is actually happening how you think it is. A quick and easy way to do that would be to just add some debug outputs like this:
void OnCollisionEnter(Collision other)
{
if (other.gameObject.tag == "Grass")
{
Debug.Log("Player hit grass");
ICanFlip = false;
flips = maxflips;
}
}
//in air
void OnCollisionExit(Collision other)
{
if (other.gameObject.tag == "Grass")
{
ICanFlip = true;
Debug.Log("Player left grass");
}
}
Now run the game and look at the output log at the bottom of unity as you play. Then you can see if these events are actually happening when/how you expect. Could be something as daft as your Grass tag actually being in lowercase when you set it up in the editor etc. Could also be that your code is working perfectly but the animation just isn't set up correctly. At least this will help narrow it down.
EDIT: Also just noticed your player script checks for "Ground" tag and your flip script checks for "Grass". Maybe you renamed the tag at some point and forgot to update the flip script?
Answer by SilverDarkwings · Sep 11, 2019 at 02:18 PM
You are correct. The game does not detect the player leaving the ground or hitting it. The PlayerController script detects it, but the flipController does not detect any changes at all Another thing I noticed is even if I directly enable the bool "ICanFlip" to be true in the inspector, the animation does not get called and stays in the idle state.
like I said in my edit (which you might not have seen), I think that's because you are checking for "Ground" in one script and "Grass" in the other. This is why its not good to rely on strings if you can avoid it
That doesn't seem to be the case here. I updated "Grass" into "Ground" but it is not detecting the player's actions. Here's what the script looks like now
public class FlipController: $$anonymous$$onoBehaviour { private int maxflips = 1; int flips; public bool ICanFlip; private Animator anim;
void Start()
{
anim = GetComponent<Animator>();
}
void Update()
{
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Space))
{
Flip();
}
}
void Flip()
{
if (ICanFlip == true && flips > 0)
{
{
anim.Play("Ninja Flip");
}
}
}
//leaves the ground
void OnCollisionEnter(Collision other)
{
if (other.gameObject.tag == "Ground")
{
Debug.Log("Player hit grass");
ICanFlip = false;
flips = maxflips;
}
}
//in air
void OnCollisionExit(Collision other)
{
if (other.gameObject.tag == "Ground")
{
ICanFlip = true;
Debug.Log("Player left grass");
}
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220612211919im_/https://answers.unity.com/themes/thub/images/avi.jpg)