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 Jack62Lewis · Aug 11, 2013 at 02:47 AM · variableupdatewaitforsecondsphone

Decrease Variable By Second Whilst Button Held

Hi,

I'm making a shooting script for a phone game that is meant to decrease my ammo variable once every second. The problem is I'm using a system where this has to happen when the player is touching down on a collider. I.e touch phase is stationary and so works every frame right?

My problem is that the variable is decreasing every frame. So, since I'm working in c#, I tried using IEnumerator and the wait seconds feature but I'm still having the dame problem since the IEnumerator is being called every frame. Need a simple work around for decreasing a variable slowly in a stationary/update type of function. Thanks.

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

3 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by whydoidoit · Aug 11, 2013 at 08:12 AM

For completeness in your answers: here is the Coroutine version of reducing a value every n seconds with a key press...

   public int ammo;
  
   void Update()
   {
         if(Input.GetKeyDown(KeyCode.Y))
         {
             StartCoroutine(DecreaseAmmoOnButton(1, KeyCode.Y));
         }
   }
  
  
   public IEnumerator DecreaseAmmoOnButton(float delay, KeyCode code)
   {
         while(Input.GetKey(code))
         {
             ammo--;
             yield return new WaitForSeconds(delay);
         }
  
   }
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 Jack62Lewis · Aug 11, 2013 at 10:48 AM 0
Share

Hello, thanks for your answer. However what would I put ins$$anonymous$$d of all the keycode stuff since I'm working with a touch phase on a GUI element?

avatar image fafase · Aug 11, 2013 at 10:57 AM 0
Share

try with Input.touchCount > 0 , you may have to perform some more raycasting to check if the touch is over the collider.

avatar image
0

Answer by dood2 · Aug 11, 2013 at 06:47 AM

I'm almost certain there is some way to do this with less code, but something like this should do. Let me know if you have any questions.

 using UnityEngine;
 using System.Collections;
 
 public class Timer 
 {
     public delegate void TimerExpiredDelegate();
     public delegate void TimerUpdateDelegate();
     
     private TimerUpdateDelegate _timerUpdate= null;
     private TimerExpiredDelegate _timerExpired= null;
     private float _startTimeSeconds= 0.0f;
     private float _currentTimeSeconds= 0.0f;
     private float _endTimeSeconds= 0.0f;
     
     public float TimerFraction { get; private set;}
     
     public bool Update(float dt)
     {
         bool result = true;
         
         _currentTimeSeconds += dt;
         
         TimerFraction = _currentTimeSeconds / (_endTimeSeconds - _startTimeSeconds);
         
         if (_currentTimeSeconds >= _endTimeSeconds)
         {
             if (_timerExpired != null)
             {
                 _timerExpired();
                 result = false;
             }
         }
         else
         {
             if (_timerUpdate != null)
             {
                 _timerUpdate();
             }
         }
         
         return result;
     }
         
     public Timer(float totalSeconds, TimerUpdateDelegate onUpdate = null, TimerExpiredDelegate onExpired = null)
     {
         _startTimeSeconds = 0.0f;
         _currentTimeSeconds = _startTimeSeconds;
         _endTimeSeconds = _startTimeSeconds + totalSeconds;
         _timerUpdate = onUpdate;
         _timerExpired = onExpired;
     }
 }
 
 public class ExampleCS : MonoBehaviour
 {
     private Timer _timer = null;
     private Timer.TimerExpiredDelegate _timerExpired = null;
     private Timer.TimerUpdateDelegate _timerUpdate = null;
     
     public float timerDuration = 1.0f; // 1 second.
     public float variableStartingValue= 10.0f;
     public float variableToDecreaseOverTime = 0.0f;
     
     private void Start()
     {
         _timerExpired = TimerExpired;
         _timerUpdate = TimerUpdate;
         variableToDecreaseOverTime= variableStartingValue;
     }
     
     private void Update()
     {
         if (Input.GetKey(KeyCode.Space))
         {
             if (_timer == null)
             {
                 Debug.Log ("Creating new timer.");
                 _timer = new Timer(timerDuration, _timerUpdate, _timerExpired);
             }
             else
             {
                 if (_timer.Update(Time.deltaTime))
                 {
                     // timer has not expired.
                 }
                 else
                 {
                     // timer has expired and the delegate will be called.                    
                 }
             }
         }
     }
     
     internal void TimerExpired()
     {
         _timer = null;
         variableToDecreaseOverTime = variableStartingValue;
         Debug.Log ("Timer expired!");
     }
     
     internal void TimerUpdate()
     {
         variableToDecreaseOverTime= variableStartingValue * (1.0f - _timer.TimerFraction);
         Debug.Log (string.Format("{0}",variableToDecreaseOverTime));
     }
 }
Comment
Add comment · 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
0

Answer by Jamora · Aug 11, 2013 at 07:20 AM

While dood's solution does follow the OOP paradigm (which is always good in my opinion), the simpler solution the OP asks for is to use InvokeRepeating. You can prevent the every frame effect by then checking IsInvoking on the counter method.

So something like this

 //if (touchphase.stationary && touching collider)
 {
 If(!IsInvoking("DecreaseAmmo"))
 InvokeRepeating("DecreaseAmmo",0f,1f);
 }
 
 //if( not touching collider)
 CancelInvoke("DecreaseAmmo");

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 dood2 · Aug 11, 2013 at 05:22 PM 0
Share

$$anonymous$$uch less code, I love it!

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

17 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

Related Questions

How often is the update function called ? 1 Answer

Variable Doesn't Update in "Update" function 0 Answers

Transfering Variables Between Sections [SOLVED] 2 Answers

Activate Animation => Wait => Hide Gameobject 2 Answers

Set guiText 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