Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Getting string from InputField (On Value Changed())

Discussion in 'UGUI & TextMesh Pro' started by Crenia, Sep 17, 2019.

  1. Crenia

    Crenia

    Joined:
    Aug 18, 2019
    Posts:
    3
    Hello All

    I am new to Unity. Most probably I miss very basic point but for the last few days I am stuck at this point and can't see the mistake. I hope someone can show me where it is.

    I use PhotonNetwork PUN for a multiplayer game and I follow the tutorials on the PUN web site.
    https://doc.photonengine.com/en-us/...al/lobby-ui#creating_the_playernameinputfield

    I follow the code written in the web site above, but still couldn't make it. Probably, I do something wrong with Input Field and On Value Changed().

    Here is my code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Photon.Pun;
    5. using Photon.Realtime;
    6. using UnityEngine.UI;
    7.  
    8. [RequireComponent(typeof(InputField))]
    9. public class NicknameInputField : MonoBehaviour
    10. {
    11.    
    12.     const string playerNamePrefKey = "PlayerName";
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.         string defaultName = string.Empty;
    17.         InputField _inputField = this.GetComponent<InputField>();
    18.         if (_inputField!=null)
    19.         {
    20.             if (PlayerPrefs.HasKey(playerNamePrefKey))
    21.             {
    22.                 defaultName = PlayerPrefs.GetString(playerNamePrefKey);
    23.                 _inputField.text = defaultName;
    24.             }
    25.         }
    26.  
    27.         PhotonNetwork.NickName =  defaultName;      
    28.     }
    29.     public void SetPlayerNickName(string value)
    30.     {
    31.         if(string.IsNullOrEmpty(value))
    32.         {
    33.             Debug.LogError("Player Name is empty");
    34.             return;
    35.         }
    36.         Debug.Log(PlayerPrefs.GetString(playerNamePrefKey));
    37.         PhotonNetwork.NickName = value;
    38.         PlayerPrefs.SetString(playerNamePrefKey,value);
    39.     }
    40.  
    41. }
    and here is the screenshot of editor for you to see On Value Changed() part.



    NicknameInputField script is attached to empty object NicknameManager. I choose SetPlayerNickname after putting NicknameManager object into Input Field.

    I did some Debug.Log and found out that string value in the function is always null. Also did some research on the internet and saw some posts about dynamic section and static section of On Value Changed(). But as you can see there is no such thing in my drop down menu.

    Sorry for the long and crowded post. I am sure the mistake will be very small and basic but i can't see it for days.
     
    amgreen333 likes this.
  2. Crenia

    Crenia

    Joined:
    Aug 18, 2019
    Posts:
    3
    nobody knows? :(
     
  3. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    I notice the "OnValueChanged" box on your Input Field has parentheses with nothing between them. That looks similar to a problem recently reported by some other users:

    Some UI elements don't have type
    Slider On Value Changed broken in OSX

    Unfortunately, no one has come up with an answer in either of those threads, either. It's possible it's a bug in a specific version of Unity?
     
  4. dancinoman

    dancinoman

    Joined:
    Jan 31, 2016
    Posts:
    11
    This thread is a bit old but I can answer :)

    Usually the string value you put between parentheses won't bring the the value from the input. But gives you which what you've put in the inspector which is empty.

    That's what you want
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Photon.Pun;
    5. using Photon.Realtime;
    6. using UnityEngine.UI;
    7. [RequireComponent(typeof(InputField))]
    8. public class NicknameInputField : MonoBehaviour
    9. {
    10.     //Assuming that the script is'nt on the Input Object
    11.    public GameObject inputFieldObj; //Add this
    12.     const string playerNamePrefKey = "PlayerName";
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.         string defaultName = string.Empty;
    17.         InputField _inputField = this.GetComponent<InputField>();
    18.         if (_inputField!=null)
    19.         {
    20.             if (PlayerPrefs.HasKey(playerNamePrefKey))
    21.             {
    22.                 defaultName = PlayerPrefs.GetString(playerNamePrefKey);
    23.                 _inputField.text = defaultName;
    24.             }
    25.         }
    26.         PhotonNetwork.NickName =  defaultName;    
    27.     }
    28.     public void SetPlayerNickName(//Leave that empty)
    29.     {
    30.        
    31.         InputField inputField = inputFieldObj.GetComponent<InputField>();
    32.          string value = inputField.text;
    33.         if(string.IsNullOrEmpty(value))
    34.         {
    35.             Debug.LogError("Player Name is empty");
    36.             return;
    37.         }
    38.         Debug.Log(PlayerPrefs.GetString(playerNamePrefKey));
    39.         PhotonNetwork.NickName = value;
    40.         PlayerPrefs.SetString(playerNamePrefKey,value);
    41.     }
    42. }
     
    berk_can likes this.
  5. HernandoNJ

    HernandoNJ

    Joined:
    May 13, 2018
    Posts:
    75
    Hello.
    I have been studying the same tutorial, and I had a tricky bug about the same issue.
    After selecting the script, I chose the same option as you --- setPlayerNickName(string) --- and it didn't work. I had to select a similar option above, but withouth parenthesis.

    a.png

    Why could that happen? Sincerely I don't know. But it seems it could be related to this line of code:

    InputField _inputField = this.GetComponent<InputField>();

    Because it is about its own input field. So, I think this is why it is necessary to attach the script to the same Name InputField -- Game Object --

    upload_2020-1-8_14-44-45.png

    Now, I tested it attaching the script to the GameObject -- empty Game Object --, drag and drop to the indicated slot. It didn't work.

    I tried again the same but attaching the script to the Name InputField -- Game Object -- too and, (although it is a weird thing), it worked.

    I hope it can help you.
     
  6. Dogeveloper

    Dogeveloper

    Joined:
    May 10, 2019
    Posts:
    8
    THANK YOU SO MUCH. This worked to me! Just needed to find the method without the parenthesees.
     
    HernandoNJ likes this.
  7. HernandoNJ

    HernandoNJ

    Joined:
    May 13, 2018
    Posts:
    75
    I'm glad it worked for you! :)
     
  8. ascavalcante80

    ascavalcante80

    Joined:
    Jun 28, 2018
    Posts:
    12
    2 years old and this thread still saving lives! Using the function without parenthesis worked perfect for me.
     
    HernandoNJ likes this.
  9. camoraz

    camoraz

    Joined:
    Jan 20, 2020
    Posts:
    3
    The option without parenthesis doesn't appear to me :(
     
    Amulo likes this.
  10. mohr023

    mohr023

    Joined:
    Jun 27, 2020
    Posts:
    3
    Considering I just had the same question and nobody went through the "why" I'll leave an explanation for what's going on. The function with parenthesis, as you can see in the editor, is meant to be used with static parameters, while the one without parenthesis works with the dynamic string coming from the input (which in this case is usually what we want).

    But definitely, thanks for pointing out and saving me a headache or two.
     
  11. Magasenakwa

    Magasenakwa

    Joined:
    Oct 13, 2018
    Posts:
    91
    I just stumbled upon this thread by accident and couldn't believe it took nearly a year for someone to explain this simple thing :O Kudos to @mohr023 for doing so.

    Just to expand on that, allow me to go into a bit more detail for those who might need it:

    You will notice that only public functions appear in the dropdown as selectable functions to call. Also worth noting is that functions must match a predefined function signature before it will display. For instance:
    Code (csharp):
    1. public void MyFunc(string value){}
    is fine and will show up just fine as something you can choose.
    Code (csharp):
    1. void MyFunc(string value){};
    2. public void MyFunc(string value1, string value2, string value3){}
    These two functions will not appear in the list.
    So to those of you who say "The function doesn't appear for me" that is why...

    If you choose a function under the "Static Parameters" list (Check the drop down, you will see it written there ;) ) then you will see a field in the inspector where you can enter a value. Let's say "Hallo world". What you are saying here is:
    Whenever the value of this field changes, please call this function and send it the value "Hallo world" every time.

    Now, if you look a little higher up you will see functions listed under "Dynamic String" (See the image 6 posts above this one). If you select one of these then you won't get the option of specifying a value in the inspector any more because what you are saying when you choose one of THESE functions is:
    Whenever the value of this field changes, please call this function and send it whatever the current value of this field is.

    So to put it simply: If you set the value in the inspector then that is the value the function will get forever. If you want to get the "current" value each time it changes then you need to initialize the text/ bool/ int/ whatever via code, not via the inspector. That should make it easy to remember

    And there you go. Mystery solved
     
    Last edited: Aug 17, 2020
  12. timebenter

    timebenter

    Joined:
    Jun 3, 2019
    Posts:
    7
    Here is how to do what you want through code:

    Code (CSharp):
    1. public TMP_InputField nameInputField;
    2.  
    3. private void Start()
    4. {  
    5.     nameInputField.onValueChanged.AddListener(UpdateInputField);
    6. }
    7.  
    8. void UpdateInputField(string data)
    9. {
    10.     print(data);
    11. }
    Data is the value of the input box. Note that I'm using TextMeshPro so just change the type of input field your using if needed.


    If you want more parameters in the UpdateInputField function then just do it like this:
    Code (CSharp):
    1. public TMP_InputField nameInputField;
    2.  
    3. private void Start()
    4. {
    5.     nameInputField.onValueChanged.AddListener((data) => { UpdateInputField(data, 5); });
    6. }
    7.  
    8. void UpdateInputField(string data, int otherData)
    9. {
    10.     print(data);
    11. }
     
    Last edited: May 18, 2021
    Hiddensquid_, LordVise, DrJBN and 2 others like this.
  13. AlexiTheHusky

    AlexiTheHusky

    Joined:
    Jan 11, 2020
    Posts:
    3
    I was experiencing a very weird bug related to ASYNC activity where the event would have the previous value unless backspace was pressed.

    It turns out the TMP Textbox calls on changed BEFORE setting the value that would be returned by GetComponent<TMP_Text>().text;

    I added a 20ms delay to allow the back end value to catch up and it seems to work fine now...

    Code (CSharp):
    1.  
    2. public async void EmailAddress_Changed()
    3.     {
    4.         await Task.Delay(20);
    5.         var text = Email;
    6.         Debug.Log($"Email changed to {text}.");
    7.  
    8.         var auth = EpicBattleClient.Instance.InputBinding.Authentication;
    9.         auth.Email = text;
    10.  
    11.         var exists = await EpicBattleClient.Instance.CheckEmailExists();
    12.         Debug.Log($"Email exists {exists}");
    13.  
    14.         LoginButtonText = exists ? "LOGIN" : "JOIN";
    15.     }
    16.  
     
  14. darkavengerpark

    darkavengerpark

    Joined:
    Jun 22, 2021
    Posts:
    2
    If you look again at the tutorial, you'll be able to see that you have to use dynamic string, not static parameters.
    upload_2022-3-17_1-5-40.png

    That's why you shouldn't use the one with parentheses.
    upload_2022-3-17_1-5-3.png
     
  15. Intraterrestrial_

    Intraterrestrial_

    Joined:
    Jun 27, 2021
    Posts:
    20
    you have to choose it below the Dynamic String of dropdown not the static
     
  16. LordVise

    LordVise

    Joined:
    Aug 1, 2020
    Posts:
    8
    Thanks. Just what I was looking for.
     
  17. Avishka1242

    Avishka1242

    Joined:
    Dec 31, 2022
    Posts:
    1
    this is the code that you missing!!
    using UnityEngine.UI;
    :)
    hope you to enjoye...............