- Home /
Unity3d Update issue
I'll make this short and clear. I got two scripts and I want to lower a number from one script to another.
Script #1 :
var healthBarDisplay : float = 1;
Script #2 :
var damage : float = 0.3f;
var Distance : float;
var attackRange : float = 1.0f;
var playerHealth : PlayerGUI;
function Awake()
{
playerHealth = GameObject.FindWithTag("Player").GetComponent(PlayerGUI);
}
function Update()
{
if(Distance < attackRange)
{
Attack();
}
}
function Attack()
{
animation.Play("Punching");
playerHealth.healthBarDisplay -= damage;
}
This is not the whole script, only a part of it, the rest has nothing to do with what Im looking for.
Now, when the distance is lower then the attack range the healthBarDisplay from script 1 goes down too fast, because it's being lowered in the update function , which updates every frame.
How do I make it so it lowers only once per second ? Adding time.deltatime doesn't work the way I want it to.
Thank you, I hope I was clear enough.
Answer by BMayne · Aug 31, 2014 at 08:14 PM
Hey There,
I would suggest using a Timer. Invoking is a little messy and puts the power in Unitys hands.
private const float ATTACK_SPEED = 1.5f;
private float nextAttack = 0.0f;
public void Update()
{
if( Distance < attackRagne )
{
if( nextAttack <= 0.0f )
{
Attack();
nextAttack = ATTACK_SPEED;
}
else
{
nextAttack -= Time.deltaTime;
}
}
else
{
nextAttack = ATTACK_SPEED;
}
}
Answer by kacyesp · Aug 31, 2014 at 07:24 PM
Since BMayne decided to 1-up me, I decided to do it back ;) Here's a pretty clean and efficient implementation. Let me know if there's something in the code below you don't understand.
private bool cooldown = true;
private bool CanAttack { get { return cooldown && Distance < attackRange; } }
function Start()
{
InvokeRepeating( "ResetCooldown", 0, 1 );
}
function Update()
{
if ( CanAttack )
Attack();
}
function Attack()
{
animation.Play("Punching");
playerHealth.healthBarDisplay -= damage;
cooldown = false;
}
void ResetCooldown() {
cooldown = true;
}
Hey $$anonymous$$acesp,
I am just not a fan of invoke for a few reasons.
$$anonymous$$agic When you are trying to debug a large portion of code it can get very hard to find out when functions are being called. The functions are being called by reflection (a very powerful but very slow library of .Net)it becomes very difficult to view the flow of your code.
Strings Suck When using Invoke you have to send the function name as a string. Strings are very slow even Unity says for animations you should use HashCodes (an int) ins$$anonymous$$d of the animation names. The other fact is that strings are prone to typos.
Giving up control Timers give you much more flexibility with your code. Say you wanted to reset your timer it's as easy as setting the current time to the start time. With Invoke you have to cancel it and then start it again (using our friend reflection again). This is very slow. If a second class wanted to know how much time was left until the function is called they would be out of luck with Invoke but with timers you can just get the remaining time.
With program$$anonymous$$g it's not about writing it easy it's about doing it right. If you take the simple way every time you are going to have more and more problems with your project down the road.
Regards, :)
Your answer
Follow this Question
Related Questions
GetComponent from class 1 Answer
my gui text write over an over in a row 1 Answer
How to access .int variable? 1 Answer
How can stop the repeat random number (Random.Range) 2 Answers
Playerprefs not saving 1 Answer