【Unity】关于 InputManager 以及改键功能的制作

前言

改键,是PC游戏中非常常用的功能。而在Unity的开发中,我们大多直接使用Unity自带的InputManager,那么这个InputManager能改键吗?

我在最近的项目开发中就遇到这个问题,结果发现,Unity自带的InputManager并不能实现代码赋值:也就是说不能改键。虽然我们经常看到Unity打PC包之后自带的启动器上有改键的功能,但是他并不能在游戏中实时修改,显然是不符合需求的。所以改键,还是要自己实现……

 

1、Unity的InputManager

在 Edit->  ProjectSettings -> Input 中,我们可以看到Unity自带的输入管理器:

从这个面板我们倒是可以进行按键修改,但是问题来了,在游戏运行时要怎么改呢?

Unity的官方文档 (https://docs.unity3d.com/560/Documentation/Manual/class-InputManager.html)里看起来像是有API的样子,但实际上并没有看到代码。我自己在工程里试来试去也没有找到相应的代码,最后在网上翻到别人的结论,说是游戏中不给改……

行吧。。。

 

2、按键输入

为了实现改键,我必须自己实现按键输入检测。好在按键输入检测其实挺简单的,就是Input.GetKey就可以,这种网上都有各种各样的示例。

我自己是用了一个列表把所有需要检测的KeyCode存起来,在Update里接收到这个值之后就开始操作:

 

3、改键

改键的逻辑挺简单的,关键在于如何侦听当前按下哪一个键了。

先上我自己的代码:

        /// <summary>
        /// 是否被选中(需要接收输入来改键);
        /// </summary>
        public bool IsFocus = false; 

        /// <summary>
        /// 按键的文本;
        /// </summary>
        public Text LabelKey;

        /// <summary>
        /// 当前按键;
        /// </summary>
        public KeyCode CurrentKeyCode;

        private void OnGUI()
        {
            if (IsFocus)
            {
                //这个Event.current居然只能在OnGUI里才能取到值,是真的秀。。。。。
                Event e = Event.current;
                if (Input.anyKeyDown)
                {
                    CurrentKeyCode = e.keyCode;
                    if (CurrentKeyCode == KeyCode.None)
                    {
                        int length = 7;
                        for (int i = 0; i < length; i++)
                        {
                            //此时有按键按下去,但是没有接受到值?
                            if (Input.GetMouseButton(i))
                                CurrentKeyCode = KeyCode.Mouse0 + i;
                        }
                    }
                    LabelKey.text = CurrentKeyCode.ToString();
                    //改键结束;
                    Cancel();
                }
                else
                {
                    LabelKey.text = WaitInputString;
                }
            }
        }

可以看到,这段代码有几个问题:

1、只能放在OnGUI里面

众所周知,OnGUI是有额外的性能消耗的,哪怕里面什么也不写。但是这个Event.Current确只有OnGUI才能取到值。无论是在FixUpdate、 Update还是LateUpdate,这个Event.Current都是空。

这是第一个坑爹的地方;

 

2、鼠标检测不到

这个Event.Current.keyCode在键盘上能正常工作,但是他检测不到鼠标!没错,所有的鼠标按键这里都会是KeyCode.None。于是你就会看到一个神奇的现象:Input.anyKeyDown为True是没错,但是到底按到什么键了呢?并不能知道。

如果你像我一样,再Input.GetMouseButton()去检测所有的鼠标按键的话,你会发现:没错他又能检测到了。

所以我才会专门关于鼠标写一个循环检测。

 

3、即便如此,鼠标上还是有一些键不能检测

就我目前所知,鼠标的侧功能键是检测不到的。也许他们并不属于MouseButton,但这个希望有大佬能解答。

 

后记

我觉得这个改键的功能Unity官方应该可以给他内置了,不然确实很蛋疼。

我看代码感觉Event这个类是要被弃用的感觉,毕竟很多检测都无效的。比如里面的说明IsShift 、 IsControl之类的属性根本没用。

  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
非常抱歉,我的回答又不正确了。在 Unity 中,确实没有 `InputManager.SetAxis` 方法。正确的做法是使用 `Input.GetAxis` 或 `Input.GetAxisRaw` 方法来获取输入值。以下是示例代码: ```c# using UnityEngine; public class WebSocketInputManager : MonoBehaviour { public string serverAddress = "ws://localhost:8080"; public string horizontalKey = "Horizontal"; public string verticalKey = "Vertical"; public float sensitivity = 1.0f; private WebSocket ws; void Awake() { ws = new WebSocket(serverAddress); ws.OnMessage += OnMessage; ws.Connect(); } void Update() { float horizontal = Input.GetAxisRaw(horizontalKey); float vertical = Input.GetAxisRaw(verticalKey); if (ws.IsAlive) { ws.Send($"{horizontalKey},{horizontal * sensitivity}"); ws.Send($"{verticalKey},{vertical * sensitivity}"); } } void OnMessage(object sender, MessageEventArgs e) { string[] values = e.Data.Split(','); if (values.Length == 2) { float value; if (float.TryParse(values[1], out value)) { if (values[0] == horizontalKey) { Input.GetAxis(horizontalKey, value); } else if (values[0] == verticalKey) { Input.GetAxis(verticalKey, value); } } } } } ``` 这个示例使用 `Input.GetAxisRaw` 获取 "Horizontal" 和 "Vertical" 输入,并通过 WebSocket 发送给服务器。当收到服务器发送的数据时,将解析的输入值设置为 `Input.GetAxis` 的返回值。这样,你就可以将 WebSocket 实时数据映射到 Unity 输入系统的 "Horizontal" 和 "Vertical" 输入了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值