# Player's knockout animation skipped when falls below

I want the player to hit the OutZone, if he falls below the ground. When he touches the OutZone, the knockout animation should be shown, followed by Respawning. In my case, when the player hits the OutZone, it gets stuck in the Jump animation, skips the knockout animation and then respawns. I've attached the details including the DeathZone script and CharacterControl script:

using UnityEngine;
using System.Collections;

public class DeathZone : MonoBehaviour {

public bool destroyNonPlayerObjects = true;

// Handle gameobjects collider with a deathzone object
void OnCollisionEnter2D (Collision2D other) {
if (other.gameObject.tag == "Player")
{
// if player then tell the player to do its FallDeath
other.gameObject.GetComponent<CharacterController2D>().FallDeath ();
} else if (destroyNonPlayerObjects) { // not playe so just kill object - could be falling enemy for example
DestroyObject(other.gameObject);
}
}
}


    using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement; // include so we can load new scenes

public class CharacterController2D : MonoBehaviour {

// player controls
[Range(0.0f, 10.0f)] // create a slider in the editor and set limits on moveSpeed
public float moveSpeed = 3f;

public float jumpForce = 600f;

// player health
public int playerHealth = 1;

// LayerMask to determine what is considered ground for the player

// Transform just below feet for checking if player is grounded
public Transform groundCheck;

// player can move?
// we want this public so other scripts can access it but we don't want to show in editor as it might confuse designer
[HideInInspector]
public bool playerCanMove = true;

// SFXs
public AudioClip coinSFX;
public AudioClip deathSFX;
public AudioClip fallSFX;
public AudioClip jumpSFX;
public AudioClip victorySFX;

// private variables below

// store references to components on the gameObject
Transform _transform;
Rigidbody2D _rigidbody;
Animator _animator;
AudioSource _audio;

// hold player motion in this timestep
float _vx;
float _vy;

// player tracking
bool facingRight = true;
bool isGrounded = false;
bool isRunning = false;
bool canDoubleJump = false;

// store the layer the player is on (setup in Awake)
int _playerLayer;

// number of layer that Platforms are on (setup in Awake)
int _platformLayer;

void Awake () {
// get a reference to the components we are going to be changing and store a reference for efficiency purposes
_transform = GetComponent<Transform> ();

_rigidbody = GetComponent<Rigidbody2D> ();
if (_rigidbody==null) // if Rigidbody is missing
Debug.LogError("Rigidbody2D component missing from this gameobject");

_animator = GetComponent<Animator>();
if (_animator==null) // if Animator is missing
Debug.LogError("Animator component missing from this gameobject");

_audio = GetComponent<AudioSource> ();
if (_audio==null) { // if AudioSource is missing
Debug.LogWarning("AudioSource component missing from this gameobject. Adding one.");
// let's just add the AudioSource component dynamically
}

// determine the player's specified layer
_playerLayer = this.gameObject.layer;

// determine the platform's specified layer
//Debug.DrawLine(_transform.position, groundCheck.position, Color.magenta);
}

// this is where most of the player controller magic happens each game event loop
void Update()
{
// exit update if player cannot move or game is paused
if (!playerCanMove || (Time.timeScale == 0f))
return;

// determine horizontal velocity change based on the horizontal input
_vx = Input.GetAxisRaw ("Horizontal");

// Determine if running based on the horizontal movement
if (_vx != 0)
{
isRunning = true;
} else {
isRunning = false;
}

// set the running animation state
_animator.SetBool("Running", isRunning);

// get the current vertical velocity from the rigidbody component
_vy = _rigidbody.velocity.y;

// Check to see if character is grounded by raycasting from the middle of the player
// down to the groundCheck position and see if collected with gameobjects on the
// whatIsGround layer
isGrounded = Physics2D.Linecast(_transform.position, groundCheck.position, whatIsGround);
Debug.DrawLine(_transform.position, groundCheck.position, Color.magenta);

//Double jump after being grounded
if(isGrounded)
{
canDoubleJump = true;
}

// Set the grounded animation states
_animator.SetBool("Grounded", isGrounded);

if (isGrounded && Input.GetButtonDown("Jump")) // If grounded AND jump button pressed, then allow the player to jump
{
DoJump();
}
else if (canDoubleJump && Input.GetButtonDown("Jump"))  //if candoublejump and jump button pressed, the player can double jump
{
DoJump();
//can doublejump once because double jump can happen only once.
canDoubleJump = false;
}

// If the player stops jumping mid jump and player is not yet falling
// then set the vertical velocity to 0 (he will start to fall from gravity)
if(Input.GetButtonUp("Jump") && _vy>0f)
{
_vy = 0f;
}

// Change the actual velocity on the rigidbody
_rigidbody.velocity = new Vector2(_vx * moveSpeed, _vy);

// if moving up then don't collide with platform layer
// this allows the player to jump up through things on the platform layer
// NOTE: requires the platforms to be on a layer named "Platform"
Physics2D.IgnoreLayerCollision(_playerLayer, _platformLayer, (_vy > 0.0f));
}

// Checking to see if the sprite should be flipped
// this is done in LateUpdate since the Animator may override the localScale
// this code will flip the player even if the animator is controlling scale
void LateUpdate()
{
// get the current scale
Vector3 localScale = _transform.localScale;

if (_vx > 0) // moving right so face right
{
facingRight = true;
} else if (_vx < 0) { // moving left so face left
facingRight = false;
}

// check to see if scale x is right for the player
// if not, multiple by -1 which is an easy way to flip a sprite
if (((facingRight) && (localScale.x<0)) || ((!facingRight) && (localScale.x>0))) {
localScale.x *= -1;
}

// update the scale
_transform.localScale = localScale;
}

// if the player collides with a MovingPlatform, then make it a child of that platform
// so it will go for a ride on the MovingPlatform
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag=="MovingPlatform")
{
this.transform.parent = other.transform;
}
}

// if the player exits a collision with a moving platform, then unchild it
void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.tag=="MovingPlatform")
{
this.transform.parent = null;
}
}

//makes the player jump
void DoJump()
{
// reset current vertical motion to 0 prior to jump
_vy = 0f;
// add a force in the up direction
// play the jump sound
PlaySound(jumpSFX);
}

// do what needs to be done to freeze the player
void FreezeMotion() {
playerCanMove = false;
_rigidbody.velocity = new Vector2(0,0);
_rigidbody.isKinematic = true;
}

// do what needs to be done to unfreeze the player
void UnFreezeMotion() {
playerCanMove = true;
_rigidbody.isKinematic = false;
}

// play sound through the audiosource on the gameobject
void PlaySound(AudioClip clip)
{
_audio.PlayOneShot(clip);
}

// public function to apply damage to the player
public void ApplyDamage (int damage) {
if (playerCanMove) {
playerHealth -= damage;

if (playerHealth <= 0) { // player is now dead, so start dying
PlaySound(deathSFX);
StartCoroutine (KillPlayer ());
}
}
}

// public function to kill the player when they have a fall death
public void FallDeath () {
if (playerCanMove) {
playerHealth = 0;
PlaySound(fallSFX);
StartCoroutine (KillPlayer ());
}
}

// coroutine to kill the player
IEnumerator KillPlayer()
{
if (playerCanMove)
{
// freeze the player
FreezeMotion();

// play the death animation
_animator.SetTrigger("Death");

// After waiting tell the GameManager to reset the game
yield return new WaitForSeconds(2.0f);

if (GameManager.gm) // if the gameManager is available, tell it to reset the game
GameManager.gm.ResetGame();
else // otherwise, just reload the current level
}
}

public void CollectCoin(int amount) {
PlaySound(coinSFX);

if (GameManager.gm) // add the points through the game manager, if it is available
}

// public function on victory over the level
public void Victory() {
PlaySound(victorySFX);
FreezeMotion ();
_animator.SetTrigger("Victory");

if (GameManager.gm) // do the game manager level compete stuff, if it is available
GameManager.gm.LevelCompete();
}

// public function to respawn the player at the appropriate location
public void Respawn(Vector3 spawnloc) {
UnFreezeMotion();
playerHealth = 1;
_transform.parent = null;
_transform.position = spawnloc;
_animator.SetTrigger("Respawn");
}
}


• This doesn't look like a minimal complete verifiable example. As we've worked through before, please try to reproduce your problem using as little code and scene/asset setup as possible, so you can isolate the potential causes. Then you can explain for us every step needed to reproduce that example. – DMGregory Jul 29 at 17:23
• Sir, I tried reproducing the problem. when the character jumps on it, the jump animation gets stuck, then it respawns. – Ishan2077 Jul 29 at 18:31
• When we talk about a reproducible example, we mean WE the readers need to be able to reproduce the problem. I should be able to create a brand new Unity project, read your question and follow all the steps / match all your settings, and at the end have a working sample that compiles and shows the problem, without any guesswork or follow-up questions. Once I can do that, I can test potential solutions to be sure they'll work for you. – DMGregory Jul 29 at 18:37
• I removed this zone so that I can create it again. When I did that, the character now slides as long as I want, doesn't respawn at all. I've added the screenshots – Ishan2077 Jul 29 at 19:07
• You forgot to tick the "Is Trigger" box - that's not related to your original question. We're still waiting on the instructions we need to demo this problem in a new, empty project. – DMGregory Jul 29 at 19:13