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 questions about integers

Discussion in 'Scripting' started by jellis88, Aug 19, 2023.

  1. jellis88

    jellis88

    Joined:
    Aug 15, 2023
    Posts:
    3
    Ok, Please don't flame me. I'm not much of a forum user, and this is my first time posting. I've had a little experience with unity, and unreal, just in more or less playing with it or maybe a few instructional videos. I haven't made anything yet, but i'm giving it my first real attempt at trying to create something playable. Now that i've said all that, I will explain what i have and the problem im having. Please feel free to speak to me as if you're speaking to a toddler, as im not much of a programmer and most if not everything ive learned so far has just been youtube videos.

    My current gameplay loop that im attempting to achieve is collecting items from one location, take them to another and drop them off. I want to decrease the amount of items on one side and increase the amount on the other side, and later i will have a mechanic that decreases from there as well. This is for a 2D game, so everything im using is 2D

    My current code for removing resources looks like this:

    Code (CSharp):
    1. public class ResourceController : MonoBehaviour
    2. {
    3.  
    4.     public int maxResources = 30;
    5.     public int currentResources;
    6.  
    7.     public GameObject barrelInHand;
    8.     public GameObject message;
    9.     public GameObject resourcePile;
    10.     public GameObject topBarrel;
    11.     public GameObject midBarrels;
    12.  
    13.  
    14.     void Start()
    15.     {
    16.         message.SetActive(false);
    17.         barrelInHand.SetActive(false);
    18.         resourcePile.SetActive(true);
    19.         currentResources = maxResources;
    20.     }
    21.  
    22.     private void OnTriggerEnter2D(Collider2D other)
    23.     {
    24.         if (other.gameObject.tag == "Player")
    25.         {
    26.             message.SetActive(true);
    27.         }
    28.     }
    29.  
    30.     private void OnTriggerExit2D(Collider2D other)
    31.     {
    32.         if (other.gameObject.tag == "Player")
    33.         {
    34.             message.SetActive(false);
    35.         }
    36.     }
    37.  
    38.     public void OnTriggerStay2D(Collider2D other)
    39.     {
    40.         if(other.gameObject.tag == "Player")
    41.         {
    42.             if (Input.GetKey(KeyCode.E))
    43.             {
    44.                 barrelInHand.SetActive(true);
    45.                 TakeResources(5);
    46.             }
    47.         }
    48.     }
    49.  
    50.     void TakeResources(int resource)
    51.     {
    52.         currentResources -= resource;
    53.     }
    54.  
    55.     public void FixedUpdate()
    56.     {
    57.         if(currentResources == 30)
    58.         {
    59.             topBarrel.SetActive(true);
    60.             midBarrels.SetActive(true);
    61.             resourcePile.SetActive(true);
    62.         }
    63.         if(currentResources <= 25)
    64.         {
    65.             topBarrel.SetActive(false);
    66.         }
    67.         if (currentResources <= 20)
    68.         {
    69.             midBarrels.SetActive(false);
    70.         }
    71.     }
    72.  
    73. }
    As im sure many of you are aware (and even myself) there is probably a much more efficient way of doing this, and i would like to learn how with some proper explanation though.

    This works "almost" the issue im having is that im attempting to reduce the resource pile from 30 by 5 at a time. Unfortunately because i'm using "OnTriggerStay2D" when i press 'E' its not taking 5, its taking however much it calculates for the timeframe im pressing 'E'. So by the time i have completed the button press sometimes im as far down as -60, when i just want to go from 30 to 25.

    I dont know what i can do to ensure the player is in the appropriate location, pressing the right button other than using ontriggerstay. Any advice would help tremendously. Sorry if i posted this in the wrong area of the forums. Like i said im new to this.
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Input.GetKey
    returns true while the key is held down. So for the period that you have the button pressed, your code is executing for every physics update. Even though physics runs slower than Update, you'll be very hard pressed to hold a button down for that fraction of a second.

    You probably ought to be using GetKeyDown: https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html so it only happens the frame the key is pressed.

    However it should be noted that polling per-frame inputs in the physics loop is unreliable. Input is best polled in Update, so your
    OnTriggerEnter/Exit2D
    methods could flip a boolean flag is the player is inside the trigger, and you can poll GetKeyDown in the regular update loop.

    Something like this:
    Code (CSharp):
    1. public class ResourceController : MonoBehaviour
    2. {
    3.     public int maxResources = 30;
    4.     public int currentResources;
    5.     public GameObject barrelInHand;
    6.     public GameObject message;
    7.     public GameObject resourcePile;
    8.     public GameObject topBarrel;
    9.     public GameObject midBarrels;
    10.  
    11.     private bool canActivate;
    12.  
    13.     private void Start()
    14.     {
    15.         message.SetActive(false);
    16.         barrelInHand.SetActive(false);
    17.         resourcePile.SetActive(true);
    18.         currentResources = maxResources;
    19.         UpdateVisuals();
    20.     }
    21.  
    22.     private void Update()
    23.     {
    24.         if (Input.GetKeyDown(KeyCode.E) && canActivate)
    25.         {
    26.             barrelInHand.SetActive(true);
    27.             TakeResources(5);
    28.         }
    29.     }
    30.  
    31.     private void OnTriggerEnter2D(Collider2D other)
    32.     {
    33.         if (other.gameObject.CompareTag("Player"))
    34.         {
    35.             message.SetActive(true);
    36.             canActivate = true;
    37.         }
    38.     }
    39.  
    40.     private void OnTriggerExit2D(Collider2D other)
    41.     {
    42.         if (other.gameObject.CompareTag("Player"))
    43.         {
    44.             message.SetActive(false);
    45.             canActivate = false;
    46.         }
    47.     }
    48.  
    49.     private void TakeResources(int resource)
    50.     {
    51.         currentResources -= resource;    
    52.         UpdateVisuals();
    53.     }
    54.  
    55.     private void UpdateVisuals()
    56.     {
    57.         if(currentResources == 30)
    58.         {
    59.             topBarrel.SetActive(true);
    60.             midBarrels.SetActive(true);
    61.             resourcePile.SetActive(true);
    62.         }
    63.  
    64.         if(currentResources <= 25)
    65.         {
    66.             topBarrel.SetActive(false);
    67.         }
    68.  
    69.         if (currentResources <= 20)
    70.         {
    71.             midBarrels.SetActive(false);
    72.         }
    73.     }
    74. }
    75.  
    I also moved the updating of visuals into a normal method, rather than FixedUpdate, as that should just be called on an as-need basis.
     
  3. jellis88

    jellis88

    Joined:
    Aug 15, 2023
    Posts:
    3
    Thank you for such a quick reply. This was what I (kinda) expected the answer to be. However, i was dissuaded to use the update as ive heard so many times and read so many times in the video/forums warnings about over using the update function as it can lead to using up too many resources down the road.

    Also as far as the boolean goes, that was the same idea i had right after posting this. I see that you have it switching back and forth in the script, but i dont see where you are depending on it being true or false. Shouldnt i add that into the update to check if its true first?
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    When you're new and learning, don't worry about this kind of stuff too much. Worrying about optimisation will just drastically slow down your learning process, and it ultimately doesn't matter in the tiny games/projects you will be playing around while learning.

    Right now just focus on getting things to work as expected. More efficient means to do certain things will come in time.

    It's in the Update method, line 24. The input only proceeds if there is input that frame, and if
    canActivate
    is true.
     
    Chubzdoomer and Qriva like this.
  5. jellis88

    jellis88

    Joined:
    Aug 15, 2023
    Posts:
    3
    Thank you for your help spiney!
     
    spiney199 likes this.