• Smoothing health transition; help.
    6 replies, posted
I can't seem to find a good or nice way of smoothing a health transition. Example: [lua]hook.Add("Tick","health",function() local health = LocalPlayer():Health() local hp = hp + (health - hp)/2 //Using the smoother EQ: (Value = Value + (TargetValue - Value)/Rate) print(tostring(hp)) end)[/lua] Of course the above won't work because hp is never really defined / initialized returning an error for trying to perform arithmetic on a nil value. Also if I define hp as 0 before the hook.. well I hope you can see the obvious arithmetic problem with dividing 0 by a number so it'll always return 0. I want to be able to do something similar to Wire Expression 2's @persist function, for if I tried doing.. [lua]@persist Health runOnTick(1) Health = Health + (owner():health() - Health)/2 print(toString(Health))[/lua] Strangely that works perfectly. How can I achieve something similar to that with Lua without having to use more lines then necessary?
Just set hp to 100 since that's the baseline?
That won't work, as either way if I define it it'll just use what I defined it as outside the hook every time in the hook. Example: [lua]local hp = 100 hook.Add("Tick","health",function() local health = LocalPlayer():Health() local hp = hp + (health - hp)/3 //Using the smoother EQ: (Value = Value + (TargetValue - Value)/Rate) LocalPlayer():ChatPrint(tostring(hp)) end)[/lua] hp will ALWAYS return 100 + (health - 100)/3, which is really not what I want as the actual value of hp does not change. EDIT: I'm trying to use it without ever defining it except that one line within the hook.
Um, no. If it's set outside of the function then it will only be set to that once. Then you can change the value as you please anywhere else in the script. Also at line 4 it's already been defined so you don't need local again.
Oh, when I remove the local it works. Thank you. [editline]10:05PM[/editline] Bah. It's still glitchy and strange even when I do get it to work using the EQ (Value = Value + (TargetValue - Value)/Rate). Is there any other possible way of getting this to work? Also I think the hook might be too fast, might use a timer. [editline]10:28PM[/editline] Now this is really starting to become a major headache. [lua]local health = 100 timer.Create("smoothHP",0.1,0,function() health = math.floor(health + (LocalPlayer():Health() - health)*0.05) LocalPlayer():ChatPrint(tostring(health)) end)[/lua] When the player loses Health it works wonders, however when the player gains health back to 100 it goes to 81 and stop there using the above code. Discovered this when I died and gained my health back, also tried checking if the players health is not 0. It seems only when the player gains health does it encounter problems. My question now is WHY?!
Dude this has to be one of the easiest things to do. First, forget whatever it is that you're doing. Now think, what do you want to do? I'm assuming you want a [b]function[/b] that [b]linearly[/b] increases health to a target value over time. It's very simple but first you need to tell me, how do you want this to work? Do you want to have a function that when called, tweens (that is, interpolates) between the current health and new health? Do you want the player to tween between [b]all[/b] changes in health (by any normal damage). Do you want this as just an effect (visual clientside effect only) or do you want the literal value of the health to tween between new and old on the server as well (I have no real idea why you would want this). If you want a visual effect only, here is the most general yet efficient way to do it. [lua] --clientside hook.Add("Think", "UpdateHealth", function() local ply = LocalPlayer() if (ply.chealth != ply:Health()) then ply.chealth = ply.chealth+RATE*FrameTime() end end) [/lua] Whenever the player's hp changes it will move at RATE until it reaches the actual hp, even if the hp changes again while it is moving. (I don't have the time to play with RATE to tell you what values to use because I forgot what size numbers FrameTime() usually returns, so you'll have to experiment, I recommend trying something between 0 and 1 or check the average value of FrameTime() in game) You can use LocalPlayer().chealth instead of LocalPlayer():Health() to render the HP bar on the HUD. If all you want is a visual effect, this is how you do it, you do [b]not[/b] change the actual health of the player.
Well that'll only increase the health, I'm trying to make it 'tween' between both increase and decrease no matter the change in value. I already stated that all I wanted to achieve was a simple way of smoothing the transition between increase and decrease in health using a value. Theres nothing visual about it other then displaying the value, in this case I'm just printing it.
Sorry, you need to Log In to post a reply to this thread.