对于Unity3D 或需要使用旧的OnGui/Gui.Button。
对于旧项目,我无法使用新的 UI,因为它需要转换整个项目。 我无法解决的问题,我在网上到处搜索信息,但找不到任何清晰且简单的解决方案来解决我的问题。 或者需要使用键盘按键选择 Gui.Button: A / S 或向上箭头/向下箭头滚动/选择所有单个 GUI 按钮。
就像您将鼠标悬停在其上一样。 我设法找到一个简单的解决方案来模拟使用键盘上的 A 键单击鼠标,是否有一个同样简单的解决方案可以做到这一点? 我谢谢
void OnGUI () {
if (GUI.Button(new Rect(25,25,100,30),Button")||Input.GetKeyUp(KeyCode.A)){
|| Input.GetKeyUp (KeyCode.A)){//this active :click :在这里输入输入键将通过添加 Up 而不是 Down 来完美模拟单帧按键。
但是对于选择单个GUI,按钮使用键盘按键?
使用按键模拟选择鼠标单GUI。按钮?
示例: 按 A/向下箭头键 = 选择:
1-桂。按钮(“开始游戏”)
按 A/向下箭头键 = 选择:
2-桂。按钮(“选项”)
按 A/向下箭头键 = 选择:
3-桂。按钮(“退出游戏”)
按 S/向上箭头键 = 选择:
1-桂。按钮(“退出游戏”)
按 S/向上箭头键 = 选择:
2-桂。按钮(“选项”)
按 S/向上箭头键 = 选择:
3-桂。按钮(“开始游戏”)
如果我理解正确的话,您想要的是选择并浏览类似于在浏览器中使用 TAB 键的控件。
正如您所说,使用内置此功能的 UI 系统非常简单。
仅使用
OnGUI
这可能有点复杂。它可以通过使用诸如GUI.SetNextControlName
,GUI.FocusControl
,GUI.GetNameOfFocusedControl
和Event.current
之类的东西来完成。
然后对于每个按钮,您需要
这是我粗略构建的一个示例来展示用法
public class Example : MonoBehaviour
{
// info about which next UI to select when pressing arrow keys
private class FocusInfo
{
public string Right {get;}
public string Left { get;}
public string Up { get;}
public string Down { get;}
public FocusInfo(string right, string left, string up, string down)
{
Right = right;
Left = left;
Up = up;
Down = down;
}
}
// info about which next UI to select when pressing arrow keys for each button
private readonly Dictionary<string, FocusInfo> focusInfos = new Dictionary<string, FocusInfo>();
// currently focused control
// used to keep focus on the last focused control even if clicked somewhere else
private string currentFocused;
private void OnGUI()
{
DrawAndRegisterButton(new Rect(10, 10, 100, 30), "Top Left",()=>
{
Debug.Log("Top Left");
}, "Top Center", null, null, "Middle Left");
DrawAndRegisterButton(new Rect(Screen.width - 110, 10, 100, 30), "Top Right",()=>
{
Debug.Log("Top Right");
}, null, "Top Center", null, "Middle Right");
DrawAndRegisterButton(new Rect(10, Screen.height - 40, 100, 30), "Bottom Left",()=>
{
Debug.Log("Bottom Left");
}, "Bottom Center", null, "Middle Left", null);
DrawAndRegisterButton(new Rect(Screen.width - 110, Screen.height - 40, 100, 30), "Bottom Right",()=>
{
Debug.Log("Bottom Right");
}, null, "Bottom Center", "Middle Right", null);
DrawAndRegisterButton(new Rect(Screen.width / 2 - 50, 10, 100, 30), "Top Center",()=>
{
Debug.Log("Top Center");
}, "Top Right", "Top Left", null, "Bottom Center");
DrawAndRegisterButton(new Rect(Screen.width / 2 - 50, Screen.height - 40, 100, 30), "Bottom Center", ()=>
{
Debug.Log("Bottom Center");
}, "Bottom Right", "Bottom Left", "Top Center", null);
DrawAndRegisterButton(new Rect(10, Screen.height / 2 - 15, 100, 30), "Middle Left", ()=>
{
Debug.Log("Middle Left");
}, "Middle Right", null, "Top Left", "Bottom Left");
DrawAndRegisterButton(new Rect(Screen.width - 110, Screen.height / 2 - 15, 100, 30), "Middle Right", ()=>
{
Debug.Log("Middle Right");
}, null, "Middle Left", "Top Right", "Bottom Right");
HandleKeybord();
InitializeOnceWithFocus("Top Left");
KeepFocusOnCurrent();
}
// Simplify drawing and registering of buttons
// Assuming for now that label = unique ID
// Includes assigning name to each control so they can be focused later
private void DrawAndRegisterButton( Rect rect, string label, Action onClick, string right, string left, string up, string down)
{
GUI.SetNextControlName(label);
if (GUI.Button(rect, label))
{
onClick?.Invoke();
}
if(!focusInfos.ContainsKey(label))
{
focusInfos.Add(label,new FocusInfo(right, left, up, down));
}
}
// At the beginning of the game, focuses the first button
private void InitializeOnceWithFocus(string focus)
{
if (!string.IsNullOrWhiteSpace(currentFocused)) return;
GUI.FocusControl(focus);
currentFocused = focus;
}
// Handles the arrow keys and focuses the next UI
private void HandleKeybord()
{
var e = Event.current;
if(e.type != EventType.KeyDown) return;
switch(e.keyCode)
{
case KeyCode.UpArrow:
case KeyCode.DownArrow:
case KeyCode.RightArrow:
case KeyCode.LeftArrow:
FocusNext(e.keyCode);
break;
}
}
// Focuses the next UI based on the arrow key pressed
private void FocusNext(KeyCode keyCode)
{
var current = GUI.GetNameOfFocusedControl();
if(!focusInfos.TryGetValue(current, out var info)) return;
var next = keyCode switch {
KeyCode.UpArrow => info.Up,
KeyCode.DownArrow => info.Down,
KeyCode.RightArrow => info.Right,
KeyCode.LeftArrow => info.Left,
_ => null
};
if(!string.IsNullOrWhiteSpace(next))
{
currentFocused = next;
GUI.FocusControl(next);
}
}
// Maintains the focus on currentFocused if e.g. clicked anywhere
private void KeepFocusOnCurrent()
{
if(!focusInfos.ContainsKey(GUI.GetNameOfFocusedControl()))
{
GUI.FocusControl(currentFocused);
}
}
}