[SOLVED] Enemy health in the animation

[My unity version is 5.5.0.f3 windows / i only made one little changes to my laser defender (my ship can move also in y direction) excepting the animations, sprites and other unimportant changes / and sry if i have some english errors :S]

Hi, i have one problem in my laser defender. i’m trying to give more hp to the enemy so that the player don’t kill the enemy so fast in the start of the animation .

[My enemy hp is 5 in idle state and my ship damage is 3]

(https://gyazo.com/63b6fde26a12138e63206e3323244071)

The problem is when you try to kill him, the enemy restarts his life every frame: (here is a sequence of images in the monodevelop debugger)

(https://gyazo.com/822cc7f49698fc4f64670ed80f662491)
(https://gyazo.com/5602d0bfe5eb942fa88697c5cb29c054)
(https://gyazo.com/580b1b50e31e5c9d596c7d8fb0c9a6ec)
and when i hit again the enemy has 5 hp again:
(https://gyazo.com/e824ef231f8b5adf029a7a9d4886ce23)

i want to learn how to instead the enemy restart his life every frame, the enemy could decrease his life every frame (for example 0.5f) and when get hitted decrease his life related with the player damage.
i tried to get the Enemy behaviour script [health] (5) in idle but is the same.

and this is my animator:

i hope i could understand how to manipulate scripts in animations to do some cool stuff in the future
Thanks to all who can help <3 ^^

You could use events in the animation, but they’re very rigid and not really suited for these kind of things, so I’ll show you directly the scripted way to do what you want to do, which is way more flexible.

You need to use the Animator State Info in order to get, frame by frame, the actual time elapsed from the start of the animation, and with that you can check if the animation clip is over or not. The code is this, the script in which to add the lines is ofc EnemyBehaviour.

These are the new class member variables and their initialization/instantiation:

[code]//You can make these private, if you don’t want them to be changed in the inspector
public float startingHealth = 150f, amountHealthToDecrease = 50f;
private bool isSpawnAnimationOver = false;
private Animator anim;

void Start(){
anim = GetComponent();
health = startingHealth;
}[/code]

Then, add this line as the first line in Update():

And finally, the method with which you’ll decrease the health during the spawning animation:

private void DecreaseHealthOnSpawn(){ AnimatorStateInfo animState = anim.GetCurrentAnimatorStateInfo(0); if (animState.normalizedTime < 1f) { // decrease health during spawn animation health -= amountHealthToDecrease * Time.deltaTime; } else { // correct final health & end spawn health decrement forever health = startingHealth - amountHealthToDecrease; isSpawnAnimationOver = true; } }

If you need more insights about specific parts of the code, feel free to ask. :slight_smile:

Thx :smiley: but i have 2 little questions
what is the layerIndex in GetCurrentAnimatorStateInfo(0)? <- that 0
and the Time.deltaTime it’s like dividing the decrease amount for every frame in the animation right?

Regarding Layers, look at this pic of the Layer tab of the Animator window:

By clicking on the + button circled in red, you can add new Layers to the Animation Controller (as I did, adding Layer (1) and Layer (2) ). Thus, whenever a method requires the int layerIndex as a parameter, you pass the index of the Layer that you want the method to operate on, in the pic the topmost (default) Base Layer is referenced by the layerIndex 0, the second one by the index 1, and the third one by the index 2 (and so on if you have more layers).

Regarding the Time.deltaTime, basically yes, you call the method every Update (every frame rendered), so in order to keep the decrement consistent in terms of seconds, you need the deltaTime.
Keep in mind that the variable amountHealthToDecrease stores the amount of health decrement per second, i.e. if the animation clip lasts 2 seconds instead of just 1, you’ll decrement by 2 * amountHealthToDecrease and not just 1*.
So, we need to fix the else part of the method by using the animation clip length to correctly give the end value of the health

private void DecreaseHealthOnSpawn(){ AnimatorStateInfo animState = anim.GetCurrentAnimatorStateInfo(0); if (animState.normalizedTime < 1f) { // decrease health during spawn animation health -= amountHealthToDecreasePerSecond * Time.deltaTime; } else { // correct final health & end spawn health decrement forever health = startingHealth - amountHealthToDecreasePerSecond * animClipLength; isSpawnAnimationOver = true; } }
and add these at the start of the class:

private float animClipLength; void Start () { animClipLength = anim.GetCurrentAnimatorClipInfo(0)[0].clip.length; }
Notice the layerIndex used by the GetCurrentAnimatorClipInfo (0) and the array index [0], which points to the first clip used by the Animator (in our case, first and only).

:smiley: Thx for the help you explain very well :slight_smile:

Privacy & Terms