Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by BUZZK1LL2000 · Sep 16, 2017 at 01:08 PM · movementbugvariablestamina

Stamina variable storing negative value? Any advice would be great :(

Hello, I need help with a simple script that disables jumping if the stamina falls below 0, this is to both limit the amount of jumping the players can do and the time in which they can do it (Stamina reduces whilst button is held, causing it to fall to 0). The problem is that even after fulling regenerating I the player should be able to jump as high (Stays enabled for same time) but instead of doing so is only able to jump about 80% of the original height. Upon logging the value of my "stamina" variable i found that even though fully generated, the stamina number would go more and more negative when pressed and then instantly go back up to 0 and regenerate once release. Any help would be great, thanks <3 (Script Below)

 using System.Collections.Generic;
 using UnityEngine;
 
 public class ForceMovementTest : MonoBehaviour {
 
     public Rigidbody rb;
     public float thrust;
     public float jump;
     private bool isjumpenabled;
     private double stamina;
     private bool isjumping;
     public bool touchleft;
     public bool touchright;
     public bool touchup;
     public Collider player;
     public Collider cube;
 
 
     // Use this for initialization
     void Start () {
     
         rb = GetComponent<Rigidbody>();
         isjumpenabled = true;
     
     }
     
     // Update is called once per frame
     void Update () {
 
         //    Checks if player is currently jumping
         if (Input.GetKey (KeyCode.W)) {
             isjumping = true;
         } else {
             isjumping = false;
         }
 
         {
             // Disables jumping if stamina equals zero
             if (stamina <= 0) {
                 isjumpenabled = false;
             } else
                 isjumpenabled = true;
         }
 
         //Moves player
         {
             if (Input.GetKey (KeyCode.D)) {
                 rb.AddForce (thrust, 0, 0, ForceMode.Acceleration);
 
             }
 
             if (Input.GetKey (KeyCode.A)) {
                 rb.AddForce (-thrust, 0, 0, ForceMode.Acceleration);
             }
             { 
                 if (isjumpenabled == true) {
                     if (Input.GetKey (KeyCode.W)) {
                         rb.AddForce (0, jump, 0, ForceMode.VelocityChange);
                         stamina = stamina - 2 * Time.time;
                         }
                 }
             }
             // Phone Controls
             if (touchright) {
                 rb.AddForce (thrust, 0, 0, ForceMode.Acceleration);
             }
             if (touchleft) {
                 rb.AddForce (-thrust, 0, 0, ForceMode.Acceleration);
             }
             { 
                 if (isjumpenabled == true) {
                     if (touchup) {
                             rb.AddForce (0, jump, 0, ForceMode.VelocityChange);
                             stamina = stamina - 1 * Time.time;
                         }
                     }
             }
         }
 
         if (isjumping == false && (stamina <30)){
             stamina = stamina + 0.05 * Time.time;
             Debug.Log (stamina);
             jump = 3;
         }
     
     
     
     }
 }
 
 
 
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Arocide · Sep 16, 2017 at 04:26 PM

Let us follow your code through the scenario that is an issue:

Player has zero stamina but is pressing the button anyway.

  • The player is holding W so we will enter this block and isjumping will be set to true (Line 31)

  • Is our stamina <= 0 ? yes so isjumpenabled will be set to false. (Line 39)

  • We know that isjumpenabled is false so we will not enter this block this update (Line 40)

  • isjumping is true so we will not enter this block either (Line 80)

So far logic is sound, maybe the problem isn't logical? Maybe we've mistaken a functions functionality? Lets have a look at the stamina drain equation used in Line 59, stamina = stamina - 2 * Time.time. I picked this to look at as stamina is being all wacky! So let's review the documentation on Time.time since we don't think it could possibly be our part of the equation causing this mess... and wait the documentation tells us that Time.time returns "The time at the beginning of this frame (Read Only). This is the time in seconds since the start of the game. "

I don't think that's what is required in this situation do you? There must be another time we can use we aren't looking for the elapsed time since the start of the game running, it's just going to make our drain increase as the game progresses. Well what else can we use? Lets take a look at where time comes from the Time class, what could be better suited to what we need. We are looking for a time which indicates the time since the last frame. deltaTime looks like a much better candidate for what we are looking for! Lets replace all our Time.time references with Time.deltaTime this will get us the intended behaviour.

While the script will do what it is supposed to do now it is very messy and does not account for say what if the player doesn't actually have the full amount of stamina to jump? Should the force that is applied be a fraction? Or is it not something we care about? If you wished to account for such a scenario and also not allow negative stamina it requires a little more logic such as:

 using System.Collections.Generic;
 using UnityEngine;
 
 public class ForceMovementTest : MonoBehaviour
 {
 
     public Rigidbody rb;
 
     //Amount of force to apply
     public float jump;
 
     //Amount of stamina that is drained per second while jumping
     public float jumpdrain;
 
     //Amount of stamina that is regenerated per second
     public float staminaRegenRate;
 
     //Maximum amount of stamina that can be held at once
     public float staminaMax;
 
     //Remaining amount of stamina
     private float stamina;
 
     void Start()
     {
         stamina = staminaMax;
         rb = GetComponent<Rigidbody>();
     }
 
     void FixedUpdate()
     {
         if (Input.GetKey(KeyCode.W))
         {
             Jump();
         }
         else
         {
             stamina += staminaRegenRate * Time.deltaTime;
             stamina = stamina < staminaMax ? stamina : staminaMax;
         }
     }
 
     void Jump()
     {
         float forceFactor = 1f;
 
         float drainAmount = jumpdrain * Time.deltaTime;
 
         if (drainAmount > stamina)
         {
             //If the drain is greater then the amount available only apply a fraction of the force
             forceFactor = stamina / drainAmount;
             stamina = 0.0f;
         }
         else
         {
             stamina -= drainAmount;
         }
         rb.AddForce(0, (jump * forceFactor) * Time.deltaTime, 0, ForceMode.VelocityChange);
     }
 }

This modified script would give you extended behaviour, such as stamina not being 0, applying only a fraction of force based on how much stamina is left when there is not enough and it is also moved into the FixedUpdate message rather then Update, which is a better place to place physics related code when possible.

Hopefully this will help you not only with your problem currently but also how to approach troubleshooting yourself as well best of luck in your Unity Adventures!

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 Flokky_ · Sep 19, 2017 at 07:24 AM 1
Share

It's better to use property to change sta$$anonymous$$a value than to check its value each time we change it. Cause, if I'll try to change its value outside of this method (in your case), then its value might became less than zero.

 [SerializeField]
 float sta$$anonymous$$a;
 
 public float Sta$$anonymous$$a
 {
   get { return sta$$anonymous$$a; }
   set 
  {
    sta$$anonymous$$a = value;
    if (sta$$anonymous$$a < 0)
    {
      sta$$anonymous$$a = 0
    }
  }
 }
    

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

153 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 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 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 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 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 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 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 avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Player keeps bumping when walking over to another sprite 1 Answer

Why does my player move without any buttons being pressed? 1 Answer

Keyboard input not working for starter FPS game 0 Answers

Add "speed" to an object every X seconds 2 Answers

Crouching and sprinting doenst work in this script 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