- Home /
Why is my Character staying in Air Idle rather than Grounded Idle?
Hey, typically I am the sort that will keep trying till I find an answer on my own, but this time I have decided that I must be doing something fundamentally wrong and somehow not seeing it.
So I am trying to get a 3 stage jump animation to play, the first part is the Lift Off (jumpIdleStart), the second is the Air Idle (airIdleBASE), and the third is the Landing (jumpIdleEnd). Getting all 3 to play properly is something else for me to figure out later but the current issue that I need help solving is really confusing to me.
When I start up my game my character defaults to the Air Idle instead of my Grounded Idle. So I went to my coding expecting some issue with my .isGrounded if statement, but after several days of experimenting I have found that it -does- recognize when my character is grounded or not, but it is for some reason playing my Air Idle anyways bypassing my else statement to do so. Then for some reason locks into the animation not recognizing my further inputs there after (not even a stutter to imply it notices the press).
I checked my animator panel in Unity and everything seems accurate with bools controlling each of them and only going to the next animation when all the rest equals false and the next location equaling true, with all being false equaling my Grounded Idle (it is the only one without a individual bool since it is the all off default)
So at this point I am at a complete loss as to what is going on here. I have tried to keep everything commented and organized for ease of reading but I am self taught and have never gone to school for programming in C# so I hope it is legible to more experienced programmers. It is also incomplete so please keep in mind that I know that some stuff is incomplete, it is a WIP project after all.
This is my entire Movement Script but again I have labeled it as best as I could:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Movement : MonoBehaviour {
/*Most are public simply for me to monitor what is going on, most
will be switched to private after the main mechanics function correctly.*/
public Animator groundMove;
public CharacterController plControl;
public GameObject climbPosition;
public Vector3 vel;
public float vertVelo;
private float moveDirX;
private float moveDirZ;
public float snapDist = 1.3f;
public float WallJDist = 1.3f;
public float walkSpd = 10.0f;
public float slowWalkSpd = 5.0f;
public float backSpd = 5.0f;
public float turnSpd = 10.0f;
public float jumpForce = 10.0f;
public float gravForce = 10.0f;
public bool Jumped = false;
public int wallJumped = 0;
public bool isInAir = false;
public bool jumpStart = false;
public bool isOnGround = false;
void Start () {
groundMove = GetComponentInChildren<Animator>();
plControl = GetComponent<CharacterController>();
}
void Update () {
SimpleJump();
SimpleMovement();
}
public void SimpleJump() {
//This is the JUMP and GRAVITY Calculations.
if(plControl.isGrounded) {
//Simple monitor to assure that it is registering grounded state correctly
isOnGround = true;
/*Jumped and wallJumped are for Double Jump and Wall Jump mechanics, there
are no animations yet and it needs refinement*/
Jumped = false;
wallJumped = 0;
//Gravity
vertVelo = -gravForce * Time.deltaTime;
/*This checks if the character was just in the air before
landing to play the landing animation. (I will use an -event-
to make it play proper later)*/
if(isInAir == true) {
groundMove.SetBool("jumpIdleEnd", true);
groundMove.SetBool("jumpIdleStart", false);
groundMove.SetBool("airIdleBASE", false);
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", false);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("turnRight", false);
isInAir = false;
groundMove.SetBool("jumpIdleEnd", false);
}
//From grounded jump
if(Input.GetKeyDown(KeyCode.Space)) {
groundMove.SetBool("jumpIdleStart", true);
groundMove.SetBool("airIdleBASE", false);
groundMove.SetBool("jumpIdleEnd", false);
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", false);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("turnRight", false);
basicJump(1);
}
}
//else, player is not grounded
else {
isOnGround = false;
isInAir = true;
//Normal gravity fall if in the air and already double jumped
if (Jumped == true) {
vertVelo -= gravForce * Time.deltaTime;
//if the player is lifing off or falling check
if (jumpStart == false) {
groundMove.SetBool("airIdleBASE", true);
groundMove.SetBool("jumpIdleStart", false);
groundMove.SetBool("jumpIdleEnd", false);
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", false);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("turnRight", false);
}
}
//if the player only jumped once
else {
//Normal gravity fall if in the air
vertVelo -= gravForce * Time.deltaTime;
if(jumpStart == false) {
groundMove.SetBool("airIdleBASE", true);
groundMove.SetBool("jumpIdleStart", false);
groundMove.SetBool("jumpIdleEnd", false);
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", false);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("turnRight", false);
}
//Double Jump
if(Input.GetKeyDown(KeyCode.Space)) {
basicJump(1);
Jumped = true;
groundMove.SetBool("jumpIdleStart", true);
groundMove.SetBool("airIdleBASE", false);
groundMove.SetBool("jumpIdleEnd", false);
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", false);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("turnRight", false);
}
}
}
}
//``````````````````````````````````````````````````````````````````````````
public void SimpleMovement() {
//This is to store the Vecor3 X and Z raw data.
Vector3 moveDir = new Vector3(0, 0, 0);
if( transform != null) {
//This is the RIGHT and LEFT buttons for TURNING the character.
transform.Rotate(0, Input.GetAxisRaw("Horizontal") * turnSpd * Time.deltaTime, 0);
//This collects the -DIRECTION- of both FORWARDS and BACKWARDS movement.
moveDir = transform.TransformDirection(Vector3.forward);
//This finds the overall SPEED of the movement plus our own value so we can change it.
float currentFSpd = walkSpd * Input.GetAxisRaw("Vertical");
float currentSFSpd = slowWalkSpd * Input.GetAxisRaw("Vertical");
float currentBSpd = backSpd * Input.GetAxisRaw("Vertical");
//This -CONVERTS- the Vector3 X and Z into FLOATS.
//FORWARDS
if(Input.GetKey(KeyCode.LeftShift) && Input.GetKey(KeyCode.W)) {
moveDirX += moveDir.x * currentSFSpd * Time.deltaTime;
moveDirZ += moveDir.z * currentSFSpd * Time.deltaTime;
}
else if(Input.GetAxisRaw("Vertical") > 0) {
moveDirX += moveDir.x * currentFSpd * Time.deltaTime;
moveDirZ += moveDir.z * currentFSpd * Time.deltaTime;
}
//BACKWARDS
if(Input.GetAxisRaw("Vertical") < 0) {
moveDirX += moveDir.x * currentBSpd * Time.deltaTime;
moveDirZ += moveDir.z * currentBSpd * Time.deltaTime;
}
//This -COMBINES- all X, Y, and Z Values into one Vector3 for ease of use.
Vector3 fullDir = new Vector3 (moveDirX, vertVelo, moveDirZ);
//This -APPLIES- the movement to the Character_Controller and thus to the -PLAYER-.
plControl.Move(fullDir);
//This -FIXES- the ramp down -JITTER- by raycasting and moving the player down.
if(plControl.isGrounded == false) {
RaycastHit hitInfo = new RaycastHit();
if(Physics.Raycast(new Ray(transform.position, Vector3.down), out hitInfo,snapDist))
plControl.Move(hitInfo.point - transform.position);
}
}
//This -RESETS- the X and Z Values back to 0 to stop -SLIDING-.
moveDirX = 0;
moveDirZ = 0;
//Controls active ground Animation.
if(Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.LeftShift)) {
groundMove.SetBool("slowWalk", true);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", false);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("turnRight", false);
}
else if(Input.GetKey(KeyCode.W)){
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", true);
groundMove.SetBool("walkBack", false);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("turnRight", false);
}
else if(Input.GetKey(KeyCode.S)) {
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", true);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("turnRight", false);
}
else if(Input.GetKey(KeyCode.A)) {
groundMove.SetBool("turnLeft", true);
groundMove.SetBool("turnRight", false);
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", false);
}
else if(Input.GetKey(KeyCode.D)) {
groundMove.SetBool("turnRight", true);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", false);
}
else {
groundMove.SetBool("slowWalk", false);
groundMove.SetBool("jogRun", false);
groundMove.SetBool("walkBack", false);
groundMove.SetBool("turnLeft", false);
groundMove.SetBool("turnRight", false);
}
}
//``````````````````````````````````````````````````````````````````````````
private void OnControllerColliderHit (ControllerColliderHit hit) {
if(!plControl.isGrounded && hit.normal.y < 0.1f)
if(Input.GetKeyDown(KeyCode.Space) && wallJumped != 4) {
Debug.DrawRay(hit.point,hit.normal,Color.red,1.25f);
Jumped = true;
vertVelo = 0;
wallJumped = wallJumped + 1;
basicJump(1.5f);
Debug.Log("Jumped");
}
}
//``````````````````````````````````````````````````````````````````````````
public void basicJump(float strength) {
//Reusable Jump which can be strengthed or weakened
vertVelo = jumpForce * strength;
//Prepping the Landing animation
if(!plControl.isGrounded) {
isInAir = true;
}
}
//``````````````````````````````````````````````````````````````````````````
public void PlayerHop(){
/*Called by another script for hopping ontop of a ledge (still a work in progress
and needs major work such as animations)*/
plControl.transform.position = climbPosition.transform.position;
}
}