我是 Unity 的新手,我的应用程序遇到了一些奇怪的问题。该程序是一个数字屏幕键盘,单击时显示按下的数字值,并在按下 Enter 按钮时将其发送到另一个函数(参见屏幕截图 1)。
到目前为止,一切都是正确的,但为了让用户能够使用数字物理键盘输入和发送数字,相同的逻辑已应用于物理数字键(参见屏幕截图 2 和 3)。
问题是,当我在使用屏幕键盘后使用物理键盘并按下键盘的 Enter 键时,它还会运行附加到屏幕键盘上单击的最后一个按钮的脚本。
这是附加到按钮编号的脚本(屏幕截图 4)。
输入按钮只需运行与第三个屏幕截图中相同的函数:GetAnswer()
我省略了我认为(希望)不相关的代码的其他部分。
总结一下,我尝试了两种提交数字的方法,但是当我将它们组合起来时,它无法正常工作。按下 Enter 键盘键时,按钮脚本也会运行,但按下其他键盘键时不会运行。
正如 BugFinder 在评论中指出的那样:Unity UI 有一个 focus / 选定的对象。
您基本上可以将其想象为一个 Web 界面,您可以使用选项卡按钮来选择不同的 UI 元素。
当您在 UI.Button
仍处于选中状态时按下
Enter时,Unity 会将其视为提交,并且会再次单击该按钮。
如上所述,为了在一个地方解决这个问题,我首先要有一个控制文本的中央控制器:
// TODO: find a better name
public class Controller : MonoBehaviour
{
[SerializeField] private TMP_Text displayText;
public void AppendValue(int value)
{
displayText.text += value.ToString();
// make sure buttons are not selected anymore after clicking
EventSystem.current.SetSelectedGameObject(null);
}
public int GetAndResetValue()
{
var value = int.Parse(displayText.text);
ResetValue();
return value;
}
public void ResetValue()
{
displayText.text = string.Empty;
// make sure also the enter button isn't selected to avoid handling the event twice
EventSystem.current.SetSelectedGameObject(null);
}
}
这样您只需在一个地方实现和维护它
然后你可以在你的按钮中使用它
public class GetNumber : MonoBehaviour
{
[SerializeField] private Controller controller;
private int value;
private void Start()
{
value = int.Parse(GetComponentInChildren<TMP_Text>().text);
}
public void getNumber()
{
controller.AppendValue(value);
}
}
和其他基于键盘的输入相同
[SerializeField] private Controller controller;
....
if(Input.GetKeyDown(KeyCode.KeyPad0))
{
controller.AppendValue(0);
}
....
private void GetAnswer()
{
var answer = controller.GetAndResetValue;
// do something with answer
}
private void Erase()
{
controller.ResetValue();
}