Search code examples
c#unity-game-engineinputinput-fieldunity3d-gui

How can I get the text and save it in InputField?


I have an array InputFields, in my situation - six InputFields. How can I get the text and save it from each InputField?

Everything should work like this: I turn on the app, I change one, two or all of the input field, then turn off the application. Again, I turn on, and input fields have to be values which I wrote earlier.

I have a code that must seem to work properly, but this code works like this: it takes only the last value entered by the user and writes it to the last input field.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SaveText : MonoBehaviour {
    public GameObject[] InputFields;
    public static string n;

    public void Start ()
{
    for(int i = 0; i < InputFields.Length; i++)
    {
        InputFields[i].GetComponent<InputField> ().text = PlayerPrefs.GetString (InputFields[i].name);
        Debug.Log (PlayerPrefs.GetString (InputFields[i].name));
        n = InputFields[i].name;
        var input = InputFields[i].GetComponent<InputField> ();
        var se = new InputField.SubmitEvent ();
        se.AddListener (SubmitName);
        input.onEndEdit = se;
    }

}

public void SubmitName(string arg)
{
    PlayerPrefs.SetString (n, arg);
}

An array of input fields I initialize dragging in Unity each input field in free cell in Script Component.


Solution

  • Well, you are using a single variable for all the different player prefs variables, n. So when you change a field (with SubmitName) it uses that n pref variable and changes it. This will correspond to the last value you gave to n in your loop.

    An option would be to have that be an array too (private string prefValues[]) or to pass the calling input field to SubmitName (or rather it's name) and use that instead of n.

    A little example (from your code you can actually change your GameObject[] to InputField[] which saves some GetComponent calls):

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class EventTest : MonoBehaviour
    {
        public InputField[] inputFields;
    
        void Start ()
        {
            foreach(InputField field in inputFields)
            {
                var se = new InputField.SubmitEvent();
                se.AddListener(delegate {
                    SubmitText(field.name, field.text);
                });
                field.onEndEdit = se;
            }
        }
    
        public void SubmitText(string prefKey, string prefVal)
        {
            Debug.Log("Saved " + prefVal + " to " + prefKey);
        }
    }
    

    Edit:
    Added lines for saving/loading from prefs in the code below. For my test setup I just have two scenes. Both have two input fields and a button that calls that scene change. I can type stuff on the fields as I like, change scenes and it stays. Also upon restarting playmode in the editor.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.SceneManagement;
    
    public class EventTest : MonoBehaviour
    {
        public InputField[] inputFields;
    
        void Start ()
        {
            foreach(InputField field in inputFields)
            {
                // Get field values from player prefs if existing
                // (it should only not exist the very first time or if you delete/clear the prefs)
                if(PlayerPrefs.HasKey(field.name))
                    field.text = PlayerPrefs.GetString(field.name);
    
                var se = new InputField.SubmitEvent();
                se.AddListener(delegate {
                    SubmitText(field.name, field.text);
                });
                field.onEndEdit = se;
            }
        }
    
        public void SubmitText(string prefKey, string prefValue)
        {
            // store the typed text of the respective input field
            PlayerPrefs.SetString(prefKey, prefValue);
        }
    
        public void ChangeScene()
        {
            if(SceneManager.GetActiveScene().name == "Scene1")
            {
                SceneManager.LoadScene("Scene2");
            }
            else
            {
                SceneManager.LoadScene("Scene1");
            }
        }
    }