【问题标题】:How to create and place input fields on a canvas via script如何通过脚本在画布上创建和放置输入字段
【发布时间】:2016-02-21 22:02:23
【问题描述】:

我的游戏有多个用户同时登录。出现一个初始输入字段,其中的数量 输入用户,例如,数字“3”表示三个用户要登录。

为了响应输入的数字,我希望 C# 脚本创建输入字段,每个用户登录一个。

以下代码在运行时接受一个数字,然后尝试创建输入字段对象。 名为“nameInputField”的初始输入字段(接受数字)是使用统一编辑器手动添加的;它是画布的孩子。

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 

代码似乎创建了一个 InputField 数组; 在运行时,如果我输入“3”,我会收到消息“IDField.Length = 3”。 但是在任何地方都没有这些输入字段的迹象:无论是在层次结构、场景还是游戏中。 此外,我放在“if”块中的任何代码,引用“IDField”的元素, 生成错误消息:“对象引用未设置为对象的实例”。 例如,“Debug.Log (IDField[i].name);”将产生该错误。

如何在运行时在画布上创建和放置这些输入字段?

【问题讨论】:

  • 一个好主意,从一个“模型”开始,然后是Instantiate
  • 谢谢。您能否告诉我在我发布的代码中如何以及在何处执行此操作?我曾想过“IDField = new InputField[NUsers] ;”这一行够了。
  • 嗨,Pat,你完全忽略了关于 Unity 的基本知识。 Unity 使用实例化的GameObject。与“普通”OO 工程完全没有联系,您只能创建一个新类。您将不得不退后一步,通过 GameObjects 了解Instantiate(包括但不限于UI 元素,例如Button)。您必须了解预制件。一旦您可以Instantiate 与其中最好的一起使用,您就可以继续使用 UI 元素了解有关 Instantiate 的详细信息

标签: c# unity3d user-input


【解决方案1】:

从根本上说,您必须了解Instantiate,这是游戏引擎中绝对基础的过程。 (游戏引擎是基于帧、基于变换和“ECS”的;它不是传统的 OO)。

你的问题需要一个

关于游戏引擎基础知识的完整教程,围绕“实例化”:

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

,在 QA 表单中并不能真正回答。

为了记录,下面是一些典型的代码来实例化一个 UI 元素,在这个例子中是一个按钮

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);
    }

作为一个额外的复杂因素,在该代码中,我使用 Unity 的布局系统 - 所以你看不到 100 行处理大小和位置的代码用户界面元素。在现实生活中,你必须做所有这些。

除其他事项外,您还必须掌握 Unity 的 UI 反应式自动布局系统

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

(您可以找到 100 多个教程和视频),和/或,掌握在代码中手动定位 UI 元素。

【讨论】:

  • 这实际上是SO上这个问题的第一个答案。
  • 谢谢乔。我是 Unity 的新手,我对它的掌握有很多漏洞。你绝对是对的;我听取了您的建议,并在我的“for循环”中放置了以下命令: IDField[i] = Instantiate(nameInputField) as InputField;瞧,当我运行游戏并在我的 nameInputField 中输入“3”时,会出现三个克隆的输入字段!感谢您为我指明正确的方向。
  • 我们日夜在这里回答您的所有问题!不要犹豫,发布一个像这样的新的好问题。 (这里的大多数统一问题都是废话。)
猜你喜欢
  • 2022-10-12
  • 1970-01-01
  • 1970-01-01
  • 2015-11-09
  • 1970-01-01
  • 2015-10-18
  • 2019-01-24
  • 2018-12-14
  • 2016-07-08
相关资源
最近更新 更多