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 How to wait for input in an update function (beginner issue)

Discussion in 'Scripting' started by styx_oarsman, Jul 21, 2023.

  1. styx_oarsman

    styx_oarsman

    Joined:
    Mar 18, 2023
    Posts:
    4
    Hi all,
    here's my situation: I'm working on a simple adventure/puzzle game concept. I'm trying to create a mechanic where a user can use an item from their inventory on an item in the game world (let's call that action 'combine'). Like this: upon finding an interactive object in the world (that has its own Combine element), the player presses the combine button (_combineAction) that would allow them to select an item from the inventory (using arrow buttons for example), upon which they would confirm the choice of item (with _selectItemAction) and then the game would pass the selected inventory item to combine function from the particular interactive object.

    My issue is this: after calling the player's combine action (currently done from within the player's update function) the game doesn't recognize the subsequent inputs... like selecting the items and confirming. I've tried different variations of loops, and also a coroutine but no luck so far. I understand that this is probably caused by the fact that update is called every frame but how to implement something like this, then? I'm very new to game programming (though not to programming as such) so not even looking for a code fix, but rather what are the concepts I need to look into? More coroutines? Unity events? Something else completely?

    My code looks sort of like this (only including the relevant parts):
    Code (CSharp):
    1. private void Update()
    2.     {
    3.  
    4.  
    5.                 // Combine
    6.                 if (_combineAction.WasPressedThisFrame() && _interactableCombine != null)
    7.                 {
    8.                     // Start at the first inv position
    9.                     int itemIndex = 0;
    10.  
    11.                     // Here the player would chose an item from the inventory - not implemented yet (always using the first item, index=0)
    12.  
    13.                     // Once you choose an item, press a button to interact
    14.                     Debug.Log($"Press {GetActionLabel(_selectItemAction)} to use item");
    15.  
    16.                    // This is the coroutine that should wait for the selectItemAction
    17.                    // _interactableCombine is the combine element of the game world object I'm trying to interact with
    18.                     waitForItemSelect(itemIndex, _interactableCombine);
    19.                 }
    20.  
    21.     }
    And this is the coroutine:
    Code (CSharp):
    1.     private IEnumerator waitForItemSelect(int itemIndex, Combine interactableCombine)
    2.     {
    3.         while (!_selectItemAction.WasPressedThisFrame())
    4.         {
    5.             yield return null;
    6.         }
    7.         var selectedItem = GetInvSlotItem(itemIndex);
    8.         // On success we should stop the selection process
    9.         if (interactableCombine.Combine(selectedItem)) Debug.Log("Success.");
    10.         // On failure we shouldn't stop but let player know it was a failure
    11.         else Debug.Log("Wrong item.");
    12.  
    13.     }
    When I run this I get the debug message prompting me to press the select key but when I do nothing happens, the coroutine is completely ignored.

    Many thanks in advance.
     
  2. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    18. StartCoroutine(waitForItemSelect(itemIndex, _interactableCombine));
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Oarsman, if you wanna get across the River Styx, you gotta START this coroutine!

    As Zulo notes, you gotta call StartCoroutine().

    Coroutines in a nutshell:

    https://forum.unity.com/threads/des...en-restarting-the-scene.1044247/#post-6758470

    https://forum.unity.com/threads/proper-way-to-stop-coroutine.704210/#post-4707821

    Splitting up larger tasks in coroutines:

    https://forum.unity.com/threads/bes...ion-so-its-non-blocking.1108901/#post-7135529

    Coroutines are NOT always an appropriate solution: know when to use them!

    "Why not simply stop having so many coroutines ffs." - orionsyndrome on Unity3D forums

    https://forum.unity.com/threads/things-to-check-before-starting-a-coroutine.1177055/#post-7538972

    https://forum.unity.com/threads/heartbeat-courutine-fx.1146062/#post-7358312

    Our very own Bunny83 has also provided a Coroutine Crash Course:

    https://answers.unity.com/questions...ected.html?childToView=1749714#answer-1749714
     
    Last edited: Jul 21, 2023
  4. styx_oarsman

    styx_oarsman

    Joined:
    Mar 18, 2023
    Posts:
    4
    Awesome, guys, thanks! Feeling rightfully stupid right now.
    @Kurt-Dekker many thanks for all the resources, I'll be sure to go through them!
     
    Kurt-Dekker likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    No need at all to feel stupid!

    After starting ten million functions with a simple
    foo();
    calling syntax, even today I still occasionally forget to wrap that with
    StartCouroutine(foo());
    when it is a coroutine. Muscle memory...

    The key is to find it fast... be on the lookout, etc.
     
  6. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    Coroutines are really messy. I still often have to look at the manual to use them. I know Invoke is frowned upon but god is it easy to use... :)