Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Variable keeps giving me a false value

Discussion in 'Scripting' started by omery15, Sep 20, 2021.

  1. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    So I am using this code and I am having problems with my 'throwing' variable.

    It keep registering as 'false' the entire time, even when I hold down the mouse button I am getting 2 entries for my log statement, one giving me true and the false one that doesn't seem to stop.

    This is the code for my class and I am using another class (script below) to give me a false value on collision

    Code (CSharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6.  
    7. public class TeleThrow : MonoBehaviour
    8. {
    9.  
    10.     bool throwing;
    11.  
    12.     private float gravityStore;     //stores the initial gravity of the player so that it can be reset after throw
    13.  
    14.     private Rigidbody2D rb2d;
    15.  
    16.     private void Awake()
    17.     {
    18.         rb2d = GetComponentInParent<Rigidbody2D>();
    19.     }
    20.  
    21.     private void Start()
    22.     {
    23.         gravityStore = rb2d.gravityScale;
    24.     }
    25.  
    26.     void Update()
    27.     {
    28.         if(Input.GetMouseButton(0))
    29.         {
    30.             FreezeThrow(true);
    31.         }
    32.  
    33.         Debug.Log(throwing);
    34.     }
    35.  
    36.     void FreezeThrow(bool throwing)
    37.     {
    38.         if(throwing)
    39.         {
    40.             rb2d.gravityScale = 4f;      
    41.             rb2d.velocity = Vector2.zero;
    42.         }
    43.  
    44.         if(!throwing)
    45.         {
    46.             rb2d.gravityScale = gravityStore;
    47.         }
    48.     }
    49.  
    50. }
    51.  
    The other class

    Code (CSharp):
    1. void OnCollisionEnter2D(Collision2D other)
    2. {
    3.     teleThrow = FindObjectOfType<TeleThrow>();
    4.     teleThrow.FreezeThrow(false);
    5. }
    Another lower priority question I have about this code is how do I arrange it so that I call the physics functions in FixedUpdate while registering the mouse inputs in Update to avoid Input loss?
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,533
    By "variable" I presume you mean the field defined in line 10? If so, you never set it to anything so why would it be anything other than the default of bool which is false?

    Looks like you're simply getting confused by the local argument (named the same) on line 36. These two are different things. You certainly shouldn't be naming them the same as it's confusing.

    You don't need to do that for the above because nothing you're doing is frame-rate dependent i.e. you're setting velocity to an absolute value which wouldn't be affected by you having 30 fps or 1000 fps. The times when this becomes important is when you're doing things like adding forces/impulses.
     
    Bunny83, Joe-Censored and Kurt-Dekker like this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,767
    This doesn't matter for continuous quantities, such as reading a position, or seeing if a key is still held down.

    Where it DOES matter is for "one frame" quantities, such as GetKeyDown() or GetMouseButtonDown(), as those are only guaranteed to return true on one precies Update() frame, which might not happen in the same frame as a FixedUpdate();

    Here's how to deal:

    1. make a private boolean variable:

    Code (csharp):
    1. private bool JumpCommanded;
    2. in Update() read and set it

    Code (csharp):
    1. // put this in Update():
    2. if (Input.GetKeyDown( KeyCode.Space))
    3. {
    4.   JumpCommanded = true;
    5. }
    3. in FixedUpdate() consume it and act on it:

    Code (csharp):
    1. // put this in FixedUpdate()
    2. if (JumpCommanded)
    3. {
    4.   JumpCommanded = false;   // this "consumes" it
    5.   // now do the actual jump force or velocity (however you are doing it) here:
    6.   myRigidbody.AddForce( Vector3.up * ImpulsiveJumpForce);
    7. }
    You can officially see this limitation in Unity's documentation for edge trigger functions only working in Update()
     
    Last edited: Mar 6, 2023
    MelvMay likes this.
  4. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    My issue is that it is only lowering the gravity when I hold the mouse button with GetMouseButton(0)), as soon as I release gravity goes back to normal even though I call "teleThrow.FreezeThrow(false);" on collision.

    Isn't it supposed to remain true until the function is called by on collision and changes it to false?
     
  5. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    So does it matter when I am changing velocities of Rigidbodies and their gravity scales?




    Does constantly reading the value of a variable in Update affect game performance or are they negligible?
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,533
    You're not reading what's been said or are not acknowledging what's been said. We don't have your project here but please take note that you're referring to the field in line 10 not changing but you never change this.

    You've got basic logic problems, don't go looking for other problems before you've got the basics down.
     
    Bunny83 likes this.
  7. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    Yes true, my bad, I understand how having the variable at line 10 be named similar to that with the local argument on line 36 is incorrect, I added it out of frustration just to see if that made a difference.

    When I do remove it completely and only have the local argument on line 36, it still runs the same way. Mainly, my gravity scale is only reduced as long as the mouse button is held, as soon as I release, gravity scale goes back to default.

    What I am trying to do is have the oncollision from my other class trigger the gravity scale back to default and until then have my gravity scale remain decreased.
     
  8. MichaelTGD

    MichaelTGD

    Joined:
    Oct 24, 2019
    Posts:
    16
    I'm not sure, but I think the issue might resolve around how you're finding the TeleThrow from the other class. You're calling to find the find any object of TeleThrow, instead of checking the object that collided with other class/object. (Or is that the point?)

    Maybe try:

    Code (CSharp):
    1. void OnCollisionEnter2D(Collision2D other)
    2. {
    3.     teleThrow = other.GetComponent<TeleThrow>();
    4.     if(teleThrow != null)
    5.     {
    6.         teleThrow.FreezeThrow(false);
    7.     }
    8. }
    With how you have it written, anytime that anything with a collider collides with this other class/object, it will call out to the first TeleThrow it can find and call the FreezeThrow method.
     
    Bunny83 likes this.
  9. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,531
    I highly doubt that. If that is all the code that actually influences the gravityScale, it will only be set back to "normal" when you have that OnCollisionEnter2D is happening. However you may just follow a redherring here. It's actually strange that you think setting the gravity scale to 4 will somehow freeze it? The normal scale is usually 1. So setting it to 4 will actually give it 4 times the gravity. So gravity is much stronger. What is actually freezing your object is that you set your velocity to 0 every frame as long as you hold down your mouse button. Of course when you release the mouse, velocity will build up again from gravity as expected. Maybe you wanted to set the gravity scale to 0?

    To be honest, it's not really clear what your game mechanic is or should be.

    About your second question at the end of your OP, you only really need to be carefull with one-time input events like GetMouseButtonDown. Querying input state can be done in FixedUpdate. Likewise one-time impulses on phyiscs objects like jumps do not need to be applied in FixedUpdate. You can apply them in Update without issues. Forces applied in Update will be taken into account the next FixedUpdate cycle.
     
  10. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    Oh wow, for some reason I thought I was defining the physics settings of gravity and decreasing it from 9.81 to 4. Even though I'm working on the Rigidbody but I just went into that chain of thought.

    I just wanted to decrease the descent of my player so lowering it to 0.2 just fixed the problem. Thanks a lot!

    So, I will need to use FixedUpdate when a somewhat continuous force is applied, so based on this, if my force mode is Impulse then it can be in Update?
     
  11. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    Yea that's kinda the point.

    Was able to fix it by fixing my gravityscale, apparently I had that all wrong. Thanks!
     
  12. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,531
    Exactly :) Since FixedUpdate may not run every frame it's unreliable to detect input that only lasts for one frame. Applying continuous forces in Update will result in a jaggy acceleration which is also not consistent across different framerates since you may have one, two or more Update cycles between the next FixedUpdate
     
  13. omery15

    omery15

    Joined:
    Mar 13, 2021
    Posts:
    55
    Awesome, thanks for clarifying that! :)