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
0
Question by Chappy · Nov 07, 2013 at 04:55 PM · c#damageinterval

Causing damage at intervals/returning a value. C#

You're going to have to excuse what is most likely going to be a dumb question but I need a bit of help here. I'm dealing with a script where I want the player to suffer damage at a set interval.

Parts of the code I'm using important to this question:

 public float DamDelay = 2.0f;
 private PlayerHealth_Test playerHealth;...
 
 playerHealth = Target.GetComponent<PlayerHealth_Test>();...

 void Update(){
 
     if (parenting == true)
     {
     Invoke ("Damage", DamDelay);
     } 
 
 } 

 void damage(){
         
         
     playerHealth.CurrentHealth -= 1.0f;
     
         
 }


I looked around the answers forum but the stuff I came upon (yield, WaitForSeconds and such) are for Javascript. Apparently Invoke is supposed to be close to that (and I've actually used Invoke before) so I ended up using that. The problem being, I don't actually have a clue how to set up a return function in C# having never had to deal with such a thing before. It doesn't help that the value I'm modifying is from another script. I know that by giving damage the void prefix it's not going to return something by definition but again, no real idea how to return a value.

So if you'll excuse the stupidity I could you some help figuring this out.

Comment
Add comment · Show 2
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 Huacanacha · Nov 07, 2013 at 05:31 PM 1
Share

A search for "Unity Coroutines C#" should set you on your way. Yield and WaitForSeconds etc are part of the Coroutine setup and definitely do work for C#.

But you may want to do something even simpler if you want to apply constant damage... you could easily set up a set of 'damageToApply' and 'damagePerSecond' variables, then apply the damage proportionally each FixedUpdate().

Btw. to return use 'return'... and find some coding tutorials ;)

avatar image Chappy · Nov 07, 2013 at 10:50 PM 0
Share

I look for tutorials when I can but I try and look for very specific tutorials, I don't have the time between classes to look for the basics as much as I would like. I tend to either find tutorials that give me just what I'm looking for at the time or head over here if I run into a wall (which I am prone to do). Learning a lot either way though. (There's also the fact that I rarely know exactly what my problem is.)

Also, I tried using return (I assumed that would, you know, return the variable but when I tried it all I got was an error.

I'll be taking a look at Coroutines when I get the chance though, that seems like it'll be useful.

3 Replies

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

Answer by Tomer-Barkan · Nov 07, 2013 at 08:12 PM

There are a few ways to go about this. One would be to use invoke, but then you need to use it only once, not every Update(), as it will call it every frame (with a starting delay of 2 seconds):

 private bool invoked = false;

 void Update() {
     if (!invoked) {
         Invoke("Damage", DamDelay);
         invoked = true;
     }
 }

 void Damage(){
     playerHealth.CurrentHealth -= 1.0f;
     invoked = false;
 }

Another would be to use coroutines like @Jix suggested.

The third, and my personal favorite, is simple, no magic, you understand exactly what happens. Simply set the time in which you want the damage to happen (current time + DamDelay), and when the time comes, do the damage and reset the timer.

 private nextDamage;

 void Start() {
     nextDamage = Time.time + DamDelay;
 }

 void Update() {
     if (nextDamage <= Time.time) {
         nextDamage = Time.time + DamDelay;
         playerHealth.CurrentHealth -= 1.0f;
     }
 }
Comment
Add comment · Show 3 · 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 Chappy · Nov 07, 2013 at 10:47 PM 0
Share

Sorry for taking so long to get back to this, I was having computer troubles.

Ah, so that why the health is dropping at a ridiculous rate, I thought it had something to do with the update but I wasn't sure.

I like your suggestion, the less hoops and such I have to jump through and the more straightforward the better. I give that a shot when I get the chance but that looks like just what I needed.

avatar image Chappy · Nov 07, 2013 at 11:43 PM 0
Share

That worked perfectly so that you again.

avatar image farspacer · Jul 28, 2014 at 09:23 AM 0
Share

Thanks a lot!

avatar image
1

Answer by Jix · Nov 07, 2013 at 05:44 PM

Please put in mind that the string in Invoke() is case sensitive, you wrote there "Damage" but you method name is "damage".

Also you are mistaken,(yield, WaitForSeconds and such) are not for Javascript only, they work for C# as well. You just need to know how use them, I'll give you an example:

     void someMethod()
     {
         StartCoroutine(damage());
     }
 
     IEnumerator damage()
     {
         yield return new WaitForSeconds(1);
         playerHealth.CurrentHealth -= 1.0f;
     }

but when you use coroutines you should know that if the script gone inactive for any reason it will stop.

I don't know if you want the damage to happen every 2 seconds or you want to delay it 2 sec. if you want it to keep calling damage() then use InvokeRepeating() instead

Comment
Add comment · Show 1 · 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 Chappy · Nov 07, 2013 at 10:38 PM 0
Share

Apologies for taking so long to get back to this, I had some computer trouble.

I realized that I messed up the string in Invoke(). I fixed that but forgot to change it in this question. It does damage but it does it much faster than I want ( I do want it do do damage every 2 seconds, or however many seconds I choose, while parenting is active).

Also, good to know about yield and such, looks like I'm going to have to look up some tutorials on that.

avatar image
1

Answer by Dracorat · Nov 07, 2013 at 05:42 PM

You should never modify variables of another class. While the language may allow it, it is bad practice.

So what you should do instead, is inside the Player_Health component, have a method like this:

 public void ApplyDamage(float howMuch){
     this.CurrentHealth -= howMuch;
 }


Then, use the method when you need it:

 playerHealth.ApplyDamage(1);

Then, if you need to add stuff like invincibility timers, etc, you can add them in the ApplyDamage routine.

As for the delay, if it's because of an environmental effect, just start a couroutine and every time the coroutine comes up for execution again, just ApplyDamage again.

Comment
Add comment · Show 1 · 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 Chappy · Nov 07, 2013 at 10:43 PM 0
Share

Sorry for taking so long to get back to this, I was having computer troubles.

So have the ApplyDamage method within the player health script and then have playerHeath.ApplyDamage(1); in the other script if I'm understanding that correctly?

That seems like it could be very useful, thank you very much.

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

19 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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Urgent help for Unity Game with deadline tomorrow 0 Answers

C# Grenade Explosion in Radius 1 Answer

Creating laser gun effect. 1 Answer


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