我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Unity制作游戏自定义按键详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Unity制作游戏自定义按键详解

一、效果图

二、布局

1.场景布局

创建一个Panel 创建三个cube,Panel地板 两个cube设置一个绿色材质,调整Scale大小让其成为柱子形状,一个cube改名为player设置一个红色材质,当作玩家(用来演示操作的),修改相机位置就可以了。

2.设置面板布局

2.1新建一个空节点名字改为SetKeyPanle,修改属性 

2.2在SetKeyPanle下新建一个image,修改名字为root,调整大小,如下图

2.3 在root下 新建Text ,修改名为Title当作标题

2.4在root下新建Scroll View组件修改属性

2.5 选择Scroll View—>Viewport—>Content对象,添加Grid Layout Group组件并修改属性

2.6 在上一步的Content下创建一个按钮改名Item,然后在这个Item下在创建两个Text,修改Item的Button组件属性

两个Text自己修改一下位置就好了,注意两个Text在父物体的孩子子级不要搞错了,第一个Text是前进,第二个是W

弄好后在吧item复制3个,有了Content的Grid Layout Group组件新建的item就不用布局了,他自动给你排列了

三、脚本思路

我们需要一个移动脚本(Player)、按键数据脚本(KeyItem)和设置面板脚本(SetKeyPanle),KeyItem脚本主要用于存储按键信息和触发修改 具体修改功能在SetKeyPanle脚本中

1.KeyItem脚本

3.1.1 获取组件 和 设置初始化按键

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using System;
 
public class KeyItem : MonoBehaviour
{
    Text key;       //按下的按键名称
    Button btn;     //开启按钮
 
    [SerializeField] KeyCode keyCode;//初始化按键 需要在面板自己选择
 
 
    void Start()
    {
        //获取组件
        key = transform.GetChild(1).GetComponent<Text>();//这里我用了子物体的孩子子级来获取
        btn = GetComponent<Button>();//按钮就获取他自己本身
 
 
    }
 
}

将这个脚本赋值给item对象,我们在面板中设置他的初始化按键

3.1.2添加修改key值、修改按钮颜色、更新失败还原按键名称 方法

 //修改key值
    void SetKeyItemValue() 
    {
        //当前有修改的key值
        if (SetKeyPanle.GetIntance().CurrentKeyItem!=null)
        {
            return;
        }
 
        //当前keyitem为空时,就让它等于自己
        SetKeyPanle.GetIntance().CurrentKeyItem = this; //这个要从SetKeyPanle脚本获取,是下面要讲的
 
        //当前状态改为true 这样就可以修改按键了
        SetKeyPanle.GetIntance().IsSet = true; //可修改  //这个要从SetKeyPanle脚本获取,是下面要讲的
        SetBtnColor(new Color32(202, 138, 138, 255));//修改按钮颜色
        key.text = "";//修改的时候text值为空
    }
 
    //修改按钮颜色
    public void SetBtnColor(Color32 color) 
    {
        btn.image.color = color; //修改颜色
    }
 
    //更新失败还原按键名称
    public void Restore() 
    {
        key.text = keyCode.ToString();
    }

3.1.3最终代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using System;
 
public class KeyItem : MonoBehaviour
{
    Text key;       //按下的按键名称
    Button btn;     //开启按钮
 
    [SerializeField] KeyCode keyCode;
 
    public KeyCode KeyCode { get { return keyCode; } 
        set { 
            keyCode = value; //修改按键值
            key.text = keyCode.ToString(); //修改按键面板要显示的Text值
        } }
 
    void Start()
    {
        key = transform.GetChild(1).GetComponent<Text>();
        btn = GetComponent<Button>();
 
        btn.onClick.AddListener(SetKeyItemValue);
 
    }
    
   //修改key值
    void SetKeyItemValue() 
    {
        //当前有修改的key值
        if (SetKeyPanle.GetIntance().CurrentKeyItem!=null)
        {
            return;
        }
 
        //当前keyitem为空时,就让它等于自己
        SetKeyPanle.GetIntance().CurrentKeyItem = this; //这个要从SetKeyPanle脚本获取,是下面要讲的
 
        //当前状态改为true 这样就可以修改按键了
        SetKeyPanle.GetIntance().IsSet = true; //可修改  //这个要从SetKeyPanle脚本获取,是下面要讲的
        SetBtnColor(new Color32(202, 138, 138, 255));//修改按钮颜色
        key.text = "";//修改的时候text值为空
    }
 
    //修改按钮颜色
    public void SetBtnColor(Color32 color) 
    {
        btn.image.color = color; //修改颜色
    }
 
    //更新失败还原按键名称
    public void Restore() 
    {
        key.text = keyCode.ToString();
    }
 
 
}

上面有几个报错的句子先不管,写完SetKeyPanle脚本的对应方法就没错了。

2.SetKeyPanle脚本

这个脚本稍微复杂,因为逻辑处理都在这里。脚本中有详细解释

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
 
//序列化按键节点
[Serializable]
public class KeyItemNode 
{
    public string keyName;//按键功能名称
    public KeyItem keyItem; //按键item
}
 
public class SetKeyPanle : MonoBehaviour
{
    KeyItem currentkeyItem=null; //当前要修改的Item
    //封装 用于判定当前是否有修改的按钮 没有为空
    public KeyItem CurrentKeyItem { get => currentkeyItem; set => currentkeyItem = value; }
 
    [SerializeField] List<KeyItemNode> keyItemList; //这个需要到面板赋值
 
    Dictionary<string, KeyItem> keyItemDic; //字典存放 键值参数 (玩家移动要用,玩家脚本后面写)
    public Dictionary<string, KeyItem> KeyItemDic { get => keyItemDic; set => keyItemDic = value; } //封装可以进行外部调用
 
    [SerializeField] Transform root; //面板节点 用于控制开启关闭面板  是上面创建设置面板UI SetKeyPanle下的root
 
 
    //单例 这样就可以获取这个脚本的方法进行使用了
    static SetKeyPanle intance;
    public static SetKeyPanle GetIntance() 
    {
        return intance;
    }
 
    void Awake() 
    {
        intance = this; //将自己赋值给intance
    }
 
    void Start()
    {
        keyItemDic = new Dictionary<string, KeyItem>();//初始化字典
 
        //将存储的按键值 添加到字典中 
        for (int i = 0; i < keyItemList.Count; i++)
        {
            keyItemDic.Add(keyItemList[i].keyName, keyItemList[i].keyItem);
        }
 
        ClosePanel(); //关闭设置面板
    }
 
    bool isCurrentOpenState = true; //当前设置面板开启的状态 true 代表开启状态 
    public bool IsCurrentOpenState { get => isCurrentOpenState; set => isCurrentOpenState = value; } //封装可以进行外部调用
 
    void Update()
    {
        //按下esc键开启关闭设置面板
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            //判断面板的开启状态
            if (isCurrentOpenState)
            {
                OpenPanel(); //开启面板
            }
            else
            {
                //判断当前是修改状态,但是你没有按下按键修改而是直接esc退出时,恢复上一次按键
                if (isSet)
                {
                    //关闭后恢复当前修改键值
                    CurrentKeyItem.Restore();
                }
 
                ClosePanel();//关闭面板
            }
 
            isCurrentOpenState = !isCurrentOpenState;
        }
        
    }
 
    #region 按键修改
 
    bool isSet = false; //是否可以修改
     public bool IsSet { get => isSet; set => isSet = value; }
 
    void OnGUI()
    {
        //可以修改
        if (isSet)
        {
            Event e = Event.current;//获取当前事件
            if (e != null && e.isKey && e.keyCode != KeyCode.None)
            {
                KeyCode currentKey = e.keyCode;
 
                //当前按键等于 ESC 时 恢复上一次按键
                if (currentKey==KeyCode.Escape)
                {
                    CurrentKeyItem.Restore();
                    return;
                }
 
                //判断是否按键冲突
                if (IsRepeat(currentKey))
                {
                    Debug.Log("按键重复!!");
                    CurrentKeyItem.Restore(); //还原按键名称
                }
                else
                    CurrentKeyItem.KeyCode = currentKey; //不重复 修改按键
 
                CurrentKeyItem.SetBtnColor(new Color32(173, 173, 173, 255)); //还原颜色
                IsSet = false;//不是修改状态
                CurrentKeyItem = null; //当前没有选择按键item
            }
        }
    }
 
    //是否重复 true 有重复
    bool IsRepeat(KeyCode keyCode) 
    {
        //循环查找是否有相同的按键
        for (int i = 0; i < keyItemList.Count; i++)
        {
            if (keyItemList[i].keyItem.KeyCode== keyCode)
            {
                return true;
            }
        }
 
        return false;
    }
 
    #endregion
 
    #region 开启关闭面板
 
    public void OpenPanel() 
    {
       root.gameObject.SetActive(true);
    }
 
    public void ClosePanel()
    {
       root.gameObject.SetActive(false);
    }
    #endregion
}

将这个脚本拖到SetKeyPanle的UI上 设置keyItemList值和root对象。如下图 :

3.player移动脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
 
public class player : MonoBehaviour
{
    public Text txt; //这个text是用来显示你按下的按键名称的,你可以随便创建在任何位置,只要赋值给他就好
    public float speed = 10f; //定义一个速度
    void Start()
    {
        
    }
 
    
    void Update()
    {
        //没有开启设置面板时 可移动
        if (SetKeyPanle.GetIntance().IsCurrentOpenState)
        {
            //前进
            if (Input.GetKey(SetKeyPanle.GetIntance().KeyItemDic["前进"].KeyCode))
            {
                transform.Translate(Vector3.forward * Time.deltaTime * speed);
                txt.text = "按下:" + SetKeyPanle.GetIntance().KeyItemDic["前进"].KeyCode.ToString();
            }
 
            //后退
            if (Input.GetKey(SetKeyPanle.GetIntance().KeyItemDic["后退"].KeyCode))
            {
                transform.Translate(Vector3.back * Time.deltaTime * speed);
                txt.text = "按下:" + SetKeyPanle.GetIntance().KeyItemDic["后退"].KeyCode.ToString();
 
            }
 
            //向左
            if (Input.GetKey(SetKeyPanle.GetIntance().KeyItemDic["向左"].KeyCode))
            {
                transform.Translate(Vector3.left * Time.deltaTime * speed);
                txt.text = "按下:" + SetKeyPanle.GetIntance().KeyItemDic["向左"].KeyCode.ToString();
 
            }
 
            //向右
            if (Input.GetKey(SetKeyPanle.GetIntance().KeyItemDic["向右"].KeyCode))
            {
                transform.Translate(Vector3.right * Time.deltaTime * speed);
                txt.text = "按下:" + SetKeyPanle.GetIntance().KeyItemDic["向右"].KeyCode.ToString();
 
            }
        }
 
    }
}

将这个脚本拖给player (场景中红色cube)赋值

好的这样我们的自定义按键功能就完成了,赶紧试试吧~~

以上就是Unity制作游戏自定义按键详解的详细内容,更多关于Unity的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Unity制作游戏自定义按键详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android自定义View制作动态炫酷按钮实例解析

普通按钮也就那么几种样式,看着都审美疲劳,先放效果图: 你会不会以为这个按钮是集结了很多动画的产物,我告诉你,并没有。所有的实现都是基于自定义View,采用最底层的onDraw一点一点的画出来的。没有采用一丁点的动画。虽然演示时间很短,
2022-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录