TheLudGamer 发表于 2021-12-3 14:56

Unity手柄控制UI

之前说的除了本地化,还有另外一个坑,就是手柄问题,在战斗部分接入手柄其实不难。麻烦的是控制UI,让UI控制非常顺手,这个才是难点。
回想之前的项目出现的问题

[*]UI选中和切换的表现不够明显
[*]UI之间的切换规则不够合理
[*]要支持退出按钮(比如键盘上的ESC或者是手柄上按B退出)
[*]希望逻辑能够简单,不要和界面逻辑功能耦合的太紧
其实做完之后发现难度还好,UGUI已经完成了很多工作,本身的


就已经支持了操控的UI切换。
解决第一点
还算好解决,可以给被选中的UI元素添加不同状态的颜色变化



或者是添加动画,当然动画是效果最好,灵活度最高的。但是很多时候我的需求非常简单


选中的时候有一个图片来标记,切换到别的时候就消失。开始敲代码。创建个继承Button的类用来做这种按钮
public class SelectButton : Button然后有一个专门被选中的图片,添加出现消失代码。(这里使用了DOTween,一行代码搞定)
      public Graphic BeSelectGraphic;
      private void ShowSelect()
        {
                BeSelectGraphic.DOFade(1, 0.3f);
        }

        private void HideSelect()
        {
                BeSelectGraphic.DOFade(0, 0.3f);
        }在选中和非选中的时候控制显隐,这里其实问题就出来了,因为父类里实现了很多接口


这里的PointEnter和Select,以及PointExit和Deselect是不相关的。所以有4个地方要添加显示隐藏的代码
        public override void OnDeselect(BaseEventData eventData)
        {
                base.OnDeselect(eventData);

                HideSelect();
        }

        public override void OnSelect(BaseEventData eventData)
        {
                base.OnSelect(eventData);

                ShowSelect();
        }

        public override void OnPointerEnter(PointerEventData eventData)
        {
                base.OnPointerEnter(eventData);

                ShowSelect();
        }

        public override void OnPointerExit(PointerEventData eventData)
        {
                base.OnPointerExit(eventData);

                HideSelect();
        }

        public override void OnPointerClick(PointerEventData eventData)
        {
                base.OnPointerClick(eventData);

                HideSelect();
        }除此之外我还在PointClick里面添加了Hide,如果不加的话,点击按钮切换到别的界面,再切换回来,按钮会保留被选中的样子。
另外要修改Editor的窗口

public class SelectButtonEditor : ButtonEditor

protected override void OnEnable()
{
        base.OnEnable();
        BeSelectGraphicProp = serializedObject.FindProperty("BeSelectGraphic");
}

public override void OnInspectorGUI()
{
        base.OnInspectorGUI();
        serializedObject.Update();
        EditorGUILayout.PropertyField(BeSelectGraphicProp);
        EditorGUILayout.Space();
        serializedObject.ApplyModifiedProperties();
}解决第二点
这个问题细化就是我希望按钮在上下左右输入的时候,按照我设定来,而不是通过UGUI自己默认的。
其实所有的选中UI都是继承自Selectable


提供切换用的上下左右的接口。为了简单我还是用刚才的SelectButton举例子。


加上上下左右要切换到的按钮


然后如果没有配置对应方向的UI,就走默认接口。如果不想切换,就在对应的UI填入自己就行,这样子按对应的方向也是保留自己不变。
解决第三点和第四点
支持取消按钮这个也不算复杂,UGUI也提供了ICancelHandler接口,还是用之前的SelectButton。


添加了一个取消事件


第四点控制当前界面下所有的可选的按钮点取消都是关闭界面,只要


把在打开界面的时候把所有可选按钮都绑定上取消事件,就可以了。
总结
当然还有很多细节都需要自己调整,比如打开另外一个界面选中按钮变成新界面上的按钮


以及代码添加UI的GameObject的切换逻辑,这个就要看自己的界面设计和摆放规则。另外就是UI之间的音效也要关注。
如果希望游戏接入手柄,最好早期的时候就接,免得最后要把界面重新拼一遍,吃力不讨好。
而且我感觉很多手游也应该接入手柄,模拟器不用绑定键位,自动支持,其实用起来也不错。另外开发的时候可以用手柄玩,感觉很棒。
最后另外介绍一个手柄的插件,我用着不错,可以很大程度上支持所有市面上的输入设备。

ainatipen 发表于 2021-12-3 15:01

大佬大佬请问unity3d 鼠标点击空白处导致按钮导航的选中状态被取消怎么解决

Mecanim 发表于 2021-12-3 15:08

如果鼠标和手柄同时控制,可以在每次鼠标切换会手柄的时候,选中一个默认的UI元素。

mypro334 发表于 2021-12-3 15:15

多人的手柄操作如何实现呢?例如格斗游戏那样,选择角色
页: [1]
查看完整版本: Unity手柄控制UI