- Home /
2D animation sprite renderer not updating
I'm currently making an animation using Unity's animation editor, for an enemy who will draw (as in draw a weapon, not draw a picture) a dagger. The enemy is a gameObject, and the dagger is a child gameObject of that enemy (with its own sprite renderer).
Initially, the dagger's sprite renderer is off, but I turn it on during the "drawdagger" animation, like this:
What happens here is that the sprite renderer gets enabled only for the duration of the animation. So I made a function (that gets called when the enemy code tells the enemy's animator to play that animation) whose job is to manually set the sprite renderer to be enabled through a reference to a gameObject. Like this:
public SpriteRenderer daggerSprite; // Reference set in inspector
//...
// Then, when it's time to play the animation:
animator.Play("drawDagger");
daggerSprite.enabled = true;
// I also have a counter here that counts down while the animation is playing
The animation plays but the dagger's sprite renderer only gets enabled for a split second while the animation is playing - when the animation finishes, the dagger's sprite renderer gets disabled again.
The code is being called, but the sprite renderer doesn't seem to listen. I also tried making daggerSprite into a GameObject and calling:
daggerSprite.GetComponent<SpriteRenderer>().enabled = true;
But that didn't work either. I know the reference is set correctly because I click the referenced object and it highlights appropriately in the scene's hierarchy.
I also tried setting the animation counter to different values, since I thought that maybe it was looping for a split second (and somehow resetting the sprite renderer to be disabled), but this doesn't seem to be the case either.
Weirdly, when I inspect the dagger gameObject in play mode, I can't enable or disable its sprite renderer - clicking the checkbox has no effect.
Also, the same thing happens "the other way around", i.e. if I initially set the dagger's sprite renderer to be enabled, and change the animation and code to disable it, the sprite gets disabled for a split second and then comes back. This is what I mean when I say it's like the sprite renderer just isn't listening to code commands. This also means it can't be the case that something elsewhere in some code is manually overriding it to be enabled or disabled.
I'm not very experienced with animating in Unity (or at all), so I guess what I want to ask is:
Is there a better way of approaching the initial problem (of having the dagger's sprite renderer be enabled during a "draw dagger" animation and then stay enabled)
If not, what can I do about the current implementation's problems?
Thanks!
Try copying the enabled keyframe you the last frame of the animation.
If it doesn't loop it should then stay like that.
An animator is not toggling a boolean that moment, but rather animates it's state that moment, so if the next keyframe or frames is basically off, then it's off. If you switch from dopesheet to curves, it should get clearer
Thanks, I did try putting the sprite renderer enabled on the last keyframe, but it didn't seem to make any difference.
Answer by FortisVenaliter · Sep 21, 2017 at 04:06 PM
I believe the correct way (take it with a grain of salt though) is to have separate animations based on what is equipped. So, you'd go from idle_unarmed to draw_dagger to idle_dagger. That way idle_unarmed can make sure the dagger is disabled while idle_dagger can make sure it's enabled.
That's certainly a valid solution; I was hoping to avoid it since it seems like a lot of effort to do something quite trivial, after all I'd be reusing the same sprites for the different animations. So while I'd have different animations for e.g. a dagger attack compared to an unarmed attack, I wanted to have general "walk" and "idle" animations that would play regardless of what the enemy has equipped, so if the enemy has a dagger equipped, it just shows in their hand during the animation since its sprite renderer is enabled.
But you're right, yours probably is the "correct" way to do it; if I can't get it working in the end using another method I'll accept your answer.
Another thing you might do is abstract it a bit. Ins$$anonymous$$d of having walk_dagger, you can have walk_onehandedmelee and just swap out the dagger sprite when using any other one-handed melee weapon. As long as the animations are the same within a group, you should be able to group them in this way. At least that way if you have many weapons, you won't have to create new animations for every single one.
Alright, I basically did what you suggested (but tweaked to fit into how I handle weapon pickups and equipment in my game). I ended up giving enemies a child "off hand weapon" game object, which has as its own child the actual e.g. dagger itself (or whatever off hand weapon that enemy has). I didn't need to create any new animations. I don't enable or disable the sprite renderer in the animation anymore, that's all done in the code at the appropriate time.
The thing is, I really don't understand why it works now and it didn't before; all that seems to have changed is that the Dagger game object is now a child of the thing that actually gets used in the animation (and so the same effects apply to it, e.g. transform changes).
Anyway thanks for your help!