Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by FluffCycle · Feb 27, 2014 at 04:56 PM · c#updateinvokerepeating

Using InvokeRepeating in the Update method?

I am trying to use the InvokeRepeating function in the Update method so that if a player comes within 4 units of the object it reduces the players health by 1 instantly and then by 1 every 5 seconds. The problem is that InvokeRepeating ignores my repeat rate and just fires constantly. Here is my code:

     void Update () {
         var dist = Vector3.Distance(player.position, transform.position);
 
         if (dist < 4)
         {
             InvokeRepeating("Damage", .0001f, 5.0f);
         }
     }

And the simple damage class:

     void Damage()
     {
         TakeDamage(1);
     }

I think the problem lies with using the InvokeRepeating() inside of the Update() method, but I'm not sure how it would be fixed. Thanks in advance!!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
5
Best Answer

Answer by robertbu · Feb 27, 2014 at 06:35 PM

A good solution for this problem is to make your damage a float. Figure out how much damage the player gets per second. Then your code might be:

 if (dist < 4)
 {
     damage -= perSecondDamage * Time.deltaTime;
 }

Or if you still want to call a function you can do:

 TakeDamage(perSecondDamage * Time.deltaTime);

If you want a regular interval of damage, a solution is the what I call a timestamp. This code will call TakeDamage() approximately every second. At the top of the file put:

 private float timestamp = 0.0f;

Then your code in the Update() loop would be:

 if (dist < 4 && Time.time >= timestmap)
 {
     TakeDamage(1);
     timestamp = Time.time + 1.0f;
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image FluffCycle · Feb 27, 2014 at 07:49 PM 0
Share

Thanks for your help! This works except for as soon as you get within 4 units it reduces by 3-5 very quickly (like the first 3-5 frames you are in range) and then it works flawlessly by reducing by one every second. I'm not sure what would be causing this as I have no other code besides this.

avatar image robertbu · Feb 27, 2014 at 10:15 PM 0
Share

I edited the answer and change line 4. This will fix the problem but introduce a very $$anonymous$$or discrepancy in the firing ti$$anonymous$$g (like 1/120 of a second).

avatar image
5

Answer by DubstepDragon · Feb 27, 2014 at 05:00 PM

The update method is for running repeatedly. Using InvokeRepeating in the update method would be like an update within an update method. InvokeRepeating should always be in the Start or Awake methods.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image FluffCycle · Feb 27, 2014 at 05:02 PM 0
Share

Thanks for your help! This is what I've gathered from reading about this problem, but I'm not sure how I would go about moving this into the start method since it needs to be activated every time the distance is less than 4 units. Any suggestions?

avatar image DubstepDragon · Feb 27, 2014 at 05:11 PM 0
Share

Well, you can use a coroutine to increment/decrement a value every set amount of time. The Unity documentation on this can be found here.

Another way of doing this would be rewriting your code in a different manner. For instance, ins$$anonymous$$d of having an InvokeRepeating method, you can do this ins$$anonymous$$d:

UPDATE:

 void Update () {
         var dist = Vector3.Distance(player.position, transform.position);
  
         if (dist < 4)
         {
             Damage();
         }
     }

DA$$anonymous$$AGE:

  void Damage()
     {
         TakeDamage(1);
     }

However doing that will run the method many times per second. If this is not what you want, you can always check out coroutines, since they do things in a fixed time. If you don't get it, reply and I will rewrite the script for you :D

Hope you understood :D

avatar image FluffCycle · Feb 27, 2014 at 06:19 PM 0
Share

Thank you so much for your help! I'm sorry to ask again, but I cant seem to understand this properly. I tried this code in the update function:

 if (dist < 4)
         {
             StartCoroutine("Damage");
             //InvokeRepeating("Damage", .0001f, 5.0f);
         }

And the Damage:

     IEnumerator Damage() //Sends amount to the TakeDamage class
     {
         TakeDamage(1);
         yield return new WaitForSeconds(5.0f);
     }

It still reduces by 1 every frame! Am I even close to having this right? Thanks again!!

avatar image DubstepDragon · Feb 27, 2014 at 07:04 PM 0
Share

Well, while I was drinking my coffee earlier, I thought of something else :D

I have an idea. You can keep your update method like this:

 void Update () {
         var dist = Vector3.Distance(player.position, transform.position);
  
         if (dist < 4)
         {
             DamageTemp();
         }
     }


Now, this will call the temporary method for damage, which is as follows:

 void DamageTemp() {
     InvokeRepeating("Damage", .0001f, 5.0f);
 }


This will start an InvokeRepeating chain for the method Damage. Now, you can have your damage method and do as follows:

  void Damage()
     {
         TakeDamage(1);
     }

So just a quick explanation of all that happened:

  • You use the update method to check if "dist" is less than 4.

  • If yes, you run the method DamageTemp().

  • That method will run the chain that will repeat with the parameters that you set (InvokeRepeating).

  • The InvokeRepeating method will now fire up the Damage() method, doing whatever you want it to do :D

Hope you learn from this! :D

If you have anything at all, any doubts, questions, feel free to comment here :D I will do my best to provide you with what you want :D

avatar image DubstepDragon · Feb 27, 2014 at 07:06 PM 0
Share

Oh and happy upvote :D

Now you have 15 $$anonymous$$arma yay! xD

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

How do I replace Invoke Repeating to allow a repeat rate change 1 Answer

GUIText not updating score.... 1 Answer

I have no idea why this isn't working 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges