Search code examples
c#unity-game-engineuser-input

How to create and place input fields on a canvas via script


My game has several users logged in at once. An initial input field appears into which the number of users is typed, e.g., the number '3' would indicate that three users want to login.

In response to the number entered, I want C# script to then create input fields, one for each user to login.

The following code accepts a number at runtime, and then attempts to create input field objects. The initial input field (to accept the number) called 'nameInputField', is added manually using the unity editor ; it is a child to a canvas.

using System;
using UnityEngine ;
using UnityEngine.UI ;
using UnityEngine.EventSystems ;

public class LoginWindow : MonoBehaviour 
{
private InputField nameInputField = null; // Assign in editor
string placeHolderText ;
int NUsers ;
InputField[] IDField;

private void Start()
{       
    placeHolderText = nameInputField.placeholder.GetComponent<Text> ().text = "Number of users ...";
    InputField.SubmitEvent submitEvent = new InputField.SubmitEvent();
    submitEvent.AddListener(SubmitName); // Add listener to catch the submit
    nameInputField.onEndEdit = submitEvent;
}

private void SubmitName(string number)
{
    Int32.TryParse(number, out NUsers) ; // convert string to number
    IDField = new InputField[NUsers] ;
    Debug.Log ("IDField.Length = " + IDField.Length );
    for (int i = 0 ; i < NUsers ; i++ ){
               // problems here !  reference to IDField[i] generates an error !
                    } // end 'for'
} // end SubmitName

} // end LoginWindow 

The code appears to create an InputField array ; at runtime, if I enter '3', I get the message "IDField.Length = 3". But there is no sign of these input fields anywhere : in neither Hierarchy, Scene nor Game. Furthermore, any code that I put within the 'if' block, referencing the elements of 'IDField', generates the error message: "Object reference not set to an instance of an object". For example, "Debug.Log (IDField[i].name);" will generate that error.

How can I create and place these input fields on the canvas at runtime ?


Solution

  • Fundamentally, you must learn about Instantiate which is the absolutely fundamental process in game engines. (Game engines are frame based, transform based, and an "ECS"; it is not conventional OO).

    Your question calls for a

    full tutiorial on the basics of a game engine, which revolves around "Instantiate":

    https://unity3d.com/learn/tutorials/modules/beginner/scripting/instantiate

    , it is not really answerable in QA form.

    For the record, following is some typical code to Instantiate a UI element, in this example a Button

    public SoundButton exampleButton;
    ...
    
    private void NewOnRight(SBB s)
        {
        GameObject nu = Instantiate(exampleButton.gameObject);
        nu.transform.SetParent(buttonsHolder, false);
        nu.SetActive(true);
        nu.name = s.soundCode;
        
        SoundButton nusb = nu.GetComponent<SoundButton>();
        
        nusb.Info = s;
        nusb.theStar.enabled = false;
        nusb.topColor = daBoss.TopColorFor(s);
        nusb.bottomColor = daBoss.BottomColorFor(s);
        }
    

    As an additional complication, in that code I'm using Unity's layout system - so you do not see 100s of lines of code dealing with the size and positioning of the UI element. In real life you'll have to do all that.

    You will have to among other things master Unity's reactive auto-layout system for UI

    http://docs.unity3d.com/Manual/comp-UIAutoLayout.html

    (you can find 100s of tutorials and videos), and/or, master manually positioning UI elements in code.