Thread Tools Display Modes
07/03/15, 12:47 AM   #1
Capadillo
Join Date: Feb 2014
Posts: 12
smooth health bar animation

I'm attempting to create a smooth health bar animation for a personal project. The goal is to eventually make it as smooth as possible, smoothing over the jumps when you do get health back. If that makes sense. Here is what I have at the moment:
Lua Code:
  1. function Animate_SetWidth(self, changeWidthTo)
  2.     -- Make sure we have a timeline & animation.
  3.     if ( not self.animation ) then
  4.         self.timeline  = ANIMATION_MANAGER:CreateTimeline();
  5.         self.animation = self.timeline:InsertAnimation(ANIMATION_SIZE, self);
  6.     end
  7.     local width = self:GetWidth();
  8.     local height = self:GetHeight();
  9.     self.animation:SetStartAndEndWidth(width, changeWidthTo)
  10.     self.animation:SetStartAndEndHeight(height, height)
  11.     self.animation:SetDuration(500)
  12.     self.animation:SetEasingFunction(ZO_EaseOutQuadratic)
  13.    
  14.     self.timeline:PlayFromStart()
  15. end
So that brings me to my questions:
  1. Is this the best way to achieve what I want?
  2. And is there a way to stop it from the start-stop animation when regaining health/magicka/stamina?

EDIT: Changing the duration to 2 seconds makes it a little less jerky but makes it seem much slower.

EDIT2: Is possible to animate a statusbar rather then creating a blank control and adding on a backdrop?

Last edited by Capadillo : 07/03/15 at 07:22 AM.
  Reply With Quote
07/03/15, 08:52 AM   #2
Sasky
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 231
1. Timelines/animations are what the game uses internally for pretty much all its animations. So, yeah, I'd stick with that for normal animations. I did some animation for CyrHUD manually, but I wanted a slow change over 10-15s, so updating at 1fps was plenty.

2. There's a stop method on the timeline:
http://wiki.esoui.com/Controls#AnimationTimeline

E1: Perhaps play with a different easing function. Without increasing FPS, "smooth" is pretty much entirely dependent on how fast/slow your transition is. Easing functions trick you by going fast for part of the progress then slower for the rest, which can appear smoother overall.

Some of the ones I found:
ZO_LinearEase, ZO_EaseOutQuadratic, ZO_EaseInQuadratic, ZO_BezierInEase

I couldn't find the exact signature for if you wanted to write your own, but the first parameter was "progress". You could probably hook one of those to get an idea of the in/out of the function. My guess is you'd feed it the actual time progress (either 0.0-1.0 or 0-100) and it'll spit out the adjusted/visual progress (same range).

E2: You can create a custom animation instead of using the size animation. It basically triggers an update for it with progress, and you can set whatever property you need:
http://wiki.esoui.com/UI_XML#CustomAnimation
http://wiki.esoui.com/Controls#AnimationObjectCustom
  Reply With Quote
07/03/15, 06:20 PM   #3
Capadillo
Join Date: Feb 2014
Posts: 12
Thanks for your response!

I'll check out how the custom animations work!

(Found a way to see ESO's code and they do it by OnUpdate so there may be another option for later on)
  Reply With Quote
07/03/15, 08:32 PM   #4
Capadillo
Join Date: Feb 2014
Posts: 12
Lua Code:
  1. local progress = {}
  2.  
  3. local function CreateSmoothProgress(control, value)
  4.     progress[control] = value;
  5. end
  6.  
  7. local function SmoothProgress()
  8.     local increment = 0.2
  9.     for control, value in pairs(progress) do
  10.         local ctrlMin, ctrlMax = control:GetMinMax();
  11.         if ( value < control:GetValue() ) then
  12.             control:SetValue(control:GetValue() - increment);
  13.         else
  14.             control:SetValue(control:GetValue() + increment);
  15.         end
  16.     end
  17. end
  18.  
  19. EVENT_MANAGER:RegisterForUpdate("SmoothProgress", 0, SmoothProgress)

As an alternative to using the animation system I wrote this. It's fairly smooth but if you change the incremental value (i.e. 0.2) to something closer to 1 then it jumps past the end of the statusbar (the leadingedge) and makes a shadow in front of it. Not sure how to combat that. Ideas?
  Reply With Quote
07/03/15, 11:27 PM   #5
Sasky
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 231
I'd try to stick to the Animation system if at all possible. Unless you're careful, you can easily do too much in an OnUpdate and cause an FPS drop. For example, that code runs every frame whether it needs to or not. Also, you're not guaranteed to actually hit your end value but could end up oscillating above/below. That part could actually be what's causing the shadow. Furthermore, that's rather brittle and doesn't allow you to change a set duration; it will change at the same speed whether you need to go a small part of the bar or the whole thing.

The animation system will handle register/deregister of the update handler for you. It's also more keyed to how long the animation is, which is more critical. The player should be able to look at the bar after .3s, .5s, probably 1s at the most and see the correct value. And if it's a small change, you can still take that time and have a smoother animation.
  Reply With Quote
07/04/15, 06:46 AM   #6
Capadillo
Join Date: Feb 2014
Posts: 12
Originally Posted by Sasky View Post
I'd try to stick to the Animation system if at all possible. Unless you're careful, you can easily do too much in an OnUpdate and cause an FPS drop. For example, that code runs every frame whether it needs to or not.
I'm still trying to figure out how to make it work the way I want it to. So I'm sure you can imagine that there is going to be bugs in my code that I have to get through...

Originally Posted by Sasky View Post
Also, you're not guaranteed to actually hit your end value but could end up oscillating above/below. That part could actually be what's causing the shadow.
Agreed, is there a solution that you could suggest? I'm coming up short of a decent solution.

Originally Posted by Sasky View Post
Furthermore, that's rather brittle and doesn't allow you to change a set duration; it will change at the same speed whether you need to go a small part of the bar or the whole thing.
The idea is to have the same speed. I do realize the drawbacks for this.

Originally Posted by Sasky View Post
The animation system will handle register/deregister of the update handler for you. It's also more keyed to how long the animation is, which is more critical. The player should be able to look at the bar after .3s, .5s, probably 1s at the most and see the correct value. And if it's a small change, you can still take that time and have a smoother animation.
You don't really see the correct value for the default attribute bars until their animation is completed anyway. I expect the same will happen no matter how you animate your bars. Unless you're happy with the bar jumping back and forth without anything smoothing. As a side note; my function looks similar to the default attribute bars. Obviously I want it to be more smoother then that though.

Again, thanks for the feedback!

Last edited by Capadillo : 07/04/15 at 07:00 AM.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » smooth health bar animation

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off