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 AfricanMoney · Oct 01, 2013 at 01:39 PM · javascriptstamina

How do I make my players stamina decrease

I have a script here, its JS. I want to decrease the Player's Stamina by 1 every 2 seconds but it decreases the Stamina by 1 every frame, so the Stamina goes crazy.

 var Speed : float = 6.0;
 var Stamina : int = 10;
 var Sprinting : boolean = false;
 var rotateSpeed : float = 3.0;
     
 function Update () 
 {
     var controller : CharacterController = GetComponent(CharacterController);
     // Rotate around y - axis
     transform.Rotate(0, Input.GetAxis ("Horizontal") * rotateSpeed, 0);
     
     // Move forward / backward
     var forward : Vector3 = transform.TransformDirection(Vector3.forward);
     var curSpeed : float = Speed * Input.GetAxis ("Vertical");
     controller.SimpleMove(forward * curSpeed);
     
     if (Input.GetKey (KeyCode.RightShift) && curSpeed > 3.0)
     {
         Speed = 13;
         Sprinting = true;
     }
     else
     {
         Speed = 6;
         Sprinting = false;
     }
     
     if (Sprinting == true)
     {
         Sprinting1 ();
     }
 }
 
 function OnGUI ()
 {
     GUI.Box (new Rect (10, 10, 100, 20), "Stamina: " + Stamina.ToString());
 }
 
 function Sprinting1 ()
 {
     if (Sprinting == true)
     {
         Sprinting2 ();
     }
 }
 
 function Sprinting2 ()
 {
     yield WaitForSeconds (2.0);
     Stamina -= 1;
     Sprinting1();
 }
 
 @script RequireComponent(CharacterController)

I used the simple move script, I add a Sprint function where when the player holds the Right Shift key the player runs faster. I also add Stamina to the player so he cant sprint forever.

When I tried to make the Stamina decrease by 1 every 2 seconds, its decreases but super fast, how can I fix it.

P.S IF THE QUESTION DOESNT MAKE SENSE IM SORRY I HAVE NO IDEA HOW TO EXPLAIN IT.

Comment
Add comment · Show 1
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 Fattie · Oct 01, 2013 at 01:39 PM 0
Share

DO not use "yield".

Use Invoke() for simple timers in Unity. You also have InvokeRepeating().

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by mattssonon · Oct 01, 2013 at 02:12 PM

You have to enable sprinting when the Shift key is pressed down, and disable sprinting when the Shift key is let go. Right now you are executing Sprinting1() every frame as long as shift is being held down. You should use GetKeyDown and GetKeyUp instead, like this:

In Update():

 if (Input.GetKeyDown(KeyCode.RightShift) && curSpeed > 3.0)
 {
     Speed = 13;
     Sprinting = true;
     // We call the sprint function here instead
     Sprinting2();
 }
 else if (Input.GetKeyUp(KeyCode.RightShift))
 {
     Speed = 6;
     Sprinting = false;
 }

Get rid of Sprinting1() and change Sprinting2() into this:

 function Sprinting2 ()
 {
     yield WaitForSeconds (2.0);
     Stamina -= 1;
     
     if (Sprinting) {
         Sprinting2();
     }
 }

Now, Sprinting2() just checks if it's still supposed to be subtracting stamina and re-runs itself if that is the case. Whenever shift is let go, it will stop subtracting stamina.

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 robertbu · Oct 01, 2013 at 02:20 PM

Your issue is lines 41 - 44. When 'Sprinting' is true, you call Sprinting2() every frame. This means you start a new coroutine every frame. If a user were to sprint for 2 seconds, and if your game was running at 60 fps, then you would stack up approximately 120 coroutines. As each coroutine comes due (i.e. 2.0 seconds has passed since its start), it will take off a point. So you will 120 coroutines reducing the stamina. And more will pile up as the sprinting continues.

As usual, I agree with @Fattie: Invoke() and InvokeRepeating() are cleaner, less error prone ways of doing something that repeats. In addition according to one analysis, they are slightly more efficient.

But I think your approach is flawed, plus I think there is a better way of accomplishing your task. Imagine the user starts to sprint then immediately stops, then 1.9 seconds later he starts again. Your code will subtract one even though the user was not sprinting the whole time. Figuring out how to track a continuous 2 seconds would take a different approach...setting a timestamp when the sprinting starts, decreasing stamina and resetting the timestamp if the current time is greater than 2 seconds in front of the timestamp.

But here is my real suggestion. Make 'Stamina' a float. Then each frame the user is sprinting:

 Stamina -= Time.deltaTime * 0.5;

You can always round 'Stamina' to an int if you need to display the value to the user. Note when you check to see if the user has stamina for sprinting, you need to check:

 if (Stamina > 0.0)

...since there is no guarentee that you will hit exactly 0.0.

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

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

16 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

Related Questions

Can someone help me fix my Javascript for Flickering Light? 6 Answers

Setting Scroll View Width GUILayout 1 Answer

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

Move Object Smoothly 1 Answer

Script not working (Java script) 2 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