- Home /
Not playing animation after been hit by bullet
Hello guys. I'm going around here in my 2d wannabe game with an animation to play on the bad guy after being hit by the bullet. I can not make her run. I can get the enemy destroyed but not play the animation first. I thought it might be for destroying the gameObject first so I put time to be destroyed but the animation still does not run and Unity does not give any error. Here is the bad guy script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BadguyScript : MonoBehaviour
{
public int maxHealth;
public int curHealth;
void Start()
{
maxHealth = 1;
curHealth = maxHealth;
}
void Update()
{
if (curHealth < 1)
{
Destroy(gameObject,2f);
GetComponent<Animation>().Play("dead_anima");
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.tag == "bullet")
{
curHealth -= 1;
Destroy(col.gameObject);
}
}
}
Any help , please?
You should use an Animator component with an Animator Controller on it, simply calling to the Animations is legacy, apart of a deprecated system.
Really that's deprecated eh?
"GetComponent().Play("dead_anima");"
over
"anim.Play("dead_anima");"
So does that mean GetComponent""(); Obsolete for newest unity?
What is the new way?
Note
$$anonymous$$ight be why i had an error helping someone earlier. What Fixed it though was a FindObjectOfType(); which i swear i saw was highly voted on to be unwise, as it searched whole scene for said type. Furthermore GameObject.FindWithTag() was recommended but required a string value input.
No the deprecated part is using "Animation" over Animator Controller. The Animation is a single animation class that IS NOT a state-machine like the new animator. There are still some good tools in the old animation system though, like blending and such. But you should use this in conjunction with the newer system. The Animator system is incredibly extensive and powerful and can be used for so many things. It's the only way with Unity to produce any kind of realistic interactions, and with a little bit of learning it quickly becomes one of the most powerful and easy to use tools in Unity.
@RobAnthem , im a starter in Unity, i look early in an animator tutorial but was a little hard for me to understand and use in this game situation. Can you help me to do that? What condition should i put in the animator? Trigger?
Answer by RobAnthem · Feb 19, 2019 at 06:09 PM
Well for most controllers of any entity, you'd have in your Animator
Locomotion (this represents your movement and idle states, usually a blend tree so you can quickly switch between Idle, Walk, and Run without ever defining more than a float)
Combat (this is all your attacks, hits, and death animations, usually you would use a sub tree here to move between them)
Complex Movement (jumping, rolling, whatever else)
Then you'd have your parameters like
speed : float //would used by the locomotion blend tree to determine which animation to play, if speed is 0 then idle, speed is > 0 < 1 then walking, if speed is 1 then running.
attack : trigger //would move the animator to your attack animation, if you have more than 1 then you'd use the next parameter as well
random : int //to determine random things, like if you have multiple attacks and want to play a specific or random one, you would have transition parameter of trigger attack AND random == x;
death //would move the animator to death animation, and be sure to prevent looping, and would stop at death animation.
hit //would move the animator to being hit animation
As well you can use Animation events to in-depthly control what happens during the animations. AnimationEvent parameters are String, Int, Float, Object, and can be VERY useful when passing information. For example when your player OR enemies attack, you'd want to add an event to the attack animation to call on the hit function to see if someone is within hit range and then pass that damage info to the appropriate entity. Sorry if this is all going over your head :(
pretty good explanation, how come you didn't make it an answer? just curious
I like to make sure it's the solution before I call it the answer.
@RobAnthem , thank you. I will try to process all that information and try to implement ... :)
Answer by titovelosa · Feb 20, 2019 at 04:27 PM
I changed my code, using animator component and the hit animation is playing now. Thank you all.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BadguyScript : MonoBehaviour
{
public int maxHealth;
public int curHealth;
private Animator myAnimator;
void Start()
{
myAnimator = GetComponent<Animator>();
myAnimator.enabled =true;
myAnimator.SetBool ("isDead",false);
maxHealth = 1;
curHealth = maxHealth;
}
void Update()
{
if (curHealth < 1)
{
myAnimator.SetBool ("isDead",true);
Destroy(gameObject,2.5f);
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.tag == "bullet")
{
curHealth -= 1;
Destroy(col.gameObject);
}
}
}
That's not 100%, you need to make sure you're bullets don't continue to hit the dead enemy while its invoking the destruction function. To do this, you should make a bool in the script for IsDead and check it in collision.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BadguyScript : $$anonymous$$onoBehaviour
{
public int maxHealth;
public int curHealth;
private Animator myAnimator;
private bool isDead;
[SerializeField]
private float DespawnTime = 2.5f;
[SerializeField]
private string DeathAnimHash = "isDead"; //this prevents hardcoding strings, and also not relevant in this situation but it prevents extra ram allocation for hardcoded stings that get reused.
void Start()
{
myAnimator = GetComponent<Animator>();
myAnimator.enabled =true;
myAnimator.SetBool (DeathAnimHash ,isDead);
maxHealth = 1;
curHealth = maxHealth;
}
void Update()
{
if (curHealth < 1)
{
isDead = true;
myAnimator.SetBool (DeathAnimHash ,isDead);
Destroy(gameObject,DespawnTime);
}
}
void OnTriggerEnter2D(Collider2D col)
{
if (isDead)
return;
if (col.tag == "bullet")
{
curHealth -= 1;
Destroy(col.gameObject);
}
}
}
Thank you, @RobAnthem for your code upgrade. It works just fine. I am very happy with my progress and with all the help of the Unity community as it is my first project. Next step, find a way to limit the number of bullets fired by the main character, with visual representation on the screen (a small image of each bullet fired disappearing at the bottom of the screen with each shot - max 6). ;)
@RobAnthem , Sorry for the abuse but just one more question. I did an animation for my character's hand to move on the gun whenever it fires. I have adapted your code and it works with only a small problem. It only plays the first time I click and fire, then no more. I've been around the code but I still have not figured out where my mistake is to make the animation play everytime i click to fire. Here is my arm code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ArmRotation : $$anonymous$$onoBehaviour
{
SpriteRenderer spriteRend;
public Transform Firepoint;
private Animator myAnimator;
private bool isFire;
private string FireAnimHash = "isFire";
void Awake()
{
spriteRend = GetComponent<SpriteRenderer>();
}
void Start()
{
myAnimator = GetComponent<Animator>();
myAnimator.enabled =true;
myAnimator.SetBool (FireAnimHash ,isFire);
}
private void Update()
{
{
AimArmAt$$anonymous$$ouse();
}
if (Input.GetButtonDown("Fire1"))
{
isFire = true;
myAnimator.SetBool (FireAnimHash ,isFire);
}
void AimArmAt$$anonymous$$ouse()
{
Vector2 mousePosition = (Vector2)Camera.main.ScreenToWorldPoint(Input.mousePosition); //get the mouse position as a Vector2
Vector2 armTo$$anonymous$$ouse = mousePosition - (Vector2)transform.position; //get the vector from the arm to the mouse
float rotationZ = Vector2.SignedAngle(transform.right, armTo$$anonymous$$ouse); //calculates the angle
transform.Rotate(0f, 0f, rotationZ); //rotates the transform by that angle
FlipArm(Vector2.SignedAngle(transform.right, Vector2.right)); //calls the FlipArm method and passes in the angle of the arm relative to the world
}
void FlipArm(float rotation)
{
if (rotation < -90f || rotation > 90f)
{
spriteRend.flipY = true;
FlipFirePoint(true);
}
else
{
spriteRend.flipY = false;
FlipFirePoint(false);
}
}
void FlipFirePoint(bool flip)
{
var pos = Firepoint.localPosition;
pos.y = $$anonymous$$athf.Abs(pos.y) * (flip ? -1 : 1);
Firepoint.localPosition = pos;
}
}
}