个人技术博客——使用PlayerPref和协程实现玩家设置按键功能
这个作业属于哪个课程 | 2021春软件工程实践S班 |
---|---|
这个作业要求在哪里 | 软件工程实践总结&个人技术博客 |
这个作业的目标 | 完成个人技术总结博客 |
其他参考文献 | bilibili、CSDN |
目录
第一部分 技术概述
- 使用该技术的情况:在Unity游戏开发中的设置菜单里面玩家修改按键
- 学习该技术的原因:完成让玩家可以自由选择按键的设置
- 技术的难点:加载到该页面时要实时获取当前按键值并且要了解PlayerPrefs类的用法还有用到协程这一概念。
第二部分 技术详述
- 按键修改功能要实现主要解决实时获取目前的按键值以及保存修改完的按键值。
加载页面获取按键当前值
- 首先要实现加载该页面时可以实时获取按键的当前值功能,采用Awake方法而不是Start方法,原因是Start方法仅在Update方法前调用且只调用一次,而Awake方法在加载脚本实例时就调用。
- 其中,获取目前的按键值的方法中先运用PlayerPrefs.GetString方法绑定初始的键值,再作为System.Enum.Parse的第二个参数,将该结果转化为KeyCode类型并保存。代码如下:
forwardkey = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("forward", "W"));
backkey = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("back", "S"));
rightkey = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("right", "D"));
leftkey = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("left", "A"));
并由GetComponent
forward.transform.Find("Text").GetComponent<Text>().text = PlayerPrefs.GetString("forward", "W");
back.transform.Find("Text").GetComponent<Text>().text = PlayerPrefs.GetString("back", "S");
right.transform.Find("Text").GetComponent<Text>().text = PlayerPrefs.GetString("right", "D");
left.transform.Find("Text").GetComponent<Text>().text = PlayerPrefs.GetString("left", "A");
手动为按钮添加点击事件
public void ForwardBtnClick()
{
currentBtn = forward; //currentBtn用于存放临时变量
isPlaying = false; //标志位
currentBtn.transform.Find("Text").GetComponent<Text>().text = "";
curKey = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("forward", "W")); //临时按键
functionName = "forward"; //保存所按按键的按键名称
isWaitingForKey = true;//等待玩家在键盘中按下按键
}
将玩家所按按键保存并呈现
if (isWaitingForKey)
{
Event e = Event.current;
if (e.isKey)
{
newKey = e.keyCode;
currentBtn.transform.Find("Text").GetComponent<Text>().text = newKey.ToString();
PlayerPrefs.SetString(functionName, newKey.ToString());
isWaitingForKey = false;//表明已按下按键,不能再按第二个按键
}
}
利用协程函数StartCoroutine()实时更新按键设置界面并用键值对保存按键
GetBindKeys();
StartCoroutine(WaitUpdate());
其中WaitUpdate函数如下
IEnumerator WaitUpdate()
{
yield return new WaitForEndOfFrame();
isPlaying = true;
}
技术使用中遇到的问题和解决过程
首先是针对于保存键值对并且之后方便进行键值对的提取的结构起初想用Map,但是Map不能持久化存储,后来通过CSDN发现了unity有自带的数据持久化方案——PlayerPrefs类,PlayerPrefs类提供了很多静态方法,可以存取程序中不同类型的数据,且对于不同的平台,它存储的路径也不一样。于是就采用了PlayerPrefs.setString()方法来存储按键的键值对。
其次是实时渲染页面按键的Text值,使用协程函数来实现实时,脚本实例一加载就调用GetBindKeys方法,之后鼠标按键保存新的键值对后再次调用GetBindKeys方法。
总结
PlayerPrefs类可以很方便地进行数据存储,尤其针对一些非关键性的数据,尤其在没有服务器的我们单机游戏饱满骑士中,游戏存档、分数排名都可以用到。
参考文献
unity update 协程
Unity生命周期方法执行顺序详解
unity自带的数据持久化方案PlayerPrefs