好久不见,在接下来的Unity随手记里,我会学着B站上的视频 [傅老師/Unity教學][4/27中午更新] DarkSouls複刻經典教程#第一季 来制作一个魂类游戏。
之前写项目脚本,输入一直都弄得简单粗暴,今天借着做这个魂类项目,再学习一下玩家输入的设计,需要事先声明的是,这套方案并非适用于所有情况。
首先,声明几个公有的变量来对输入的键进行封装。这样方便我们通过多种手段对按键进行修改。比如有时候,玩家使用键鼠进行输入,而有时候使用手柄、VR设备进行输入。这里我们定义了上下左右四个按键。
// 上下左右
public string keyUp = "w";
public string keyDown = "s";
public string keyLeft = "a";
public string keyRight = "d";
// 功能按键 跑 跳 蹲 攻击...
// ...
接下来,根据上下左右再定义两个方向轴,up和right。将获取的四键输入转化为双轴输入。
// 将上下键的输入整合 计算向上方向的输入大小
m_targetDirUp =
((Input.GetKey(keyUp) ? 1.0f : 0) - (Input.GetKey(keyDown) ? 1.0f : 0));
// 将左右键的输入整合 计算向右方向的输入大小
m_targetDirRight =
((Input.GetKey(keyRight) ? 1.0f : 0) - (Input.GetKey(keyLeft) ? 1.0f : 0));
你也可以选择GetAxis,这里是老师自己写的逻辑。
按照之前的做法,我们的输入是突变的(用了GetAxis就当没有)。如果要得到一个渐变的输入,我们可以采用SmoothDamp。
// damp之后的 向上/向右 方向值
public float dirUp;
public float dirRight;
// 向上/向右 的最终方向值 用于将四键输入转换为双轴输入
private float targetDirUp;
private float targetDirRight;
// 向上/向右 damp的currentVelocity参数
private float velocityDirUp;
private float velocityDirRight;
// 输入的damp时间
public float dampTime = 1.0f;
现在,除了使用targetDirUp和targetDirRight来表示最终要达到的方向值,再使用一套参数dirUp和dirRight来记录SmoothDamp之后得到的方向值。
// 运用SmoothDamp来获得渐变的输入变化
dirUp = Mathf.SmoothDamp(dirUp, targetDirUp, ref velocityDirUp, dampTime);
dirRight = Mathf.SmoothDamp(dirRight, targetDirRight, ref velocityDirRight, dampTime);
在不直接关闭脚本组件的情况下,对脚本中的参数进行修改来达到使组件失效的效果,这样的开关叫做软开关。
我们可以对我们的输入模块实现一个软开关,方法是定义设置一个bool值inputEnabled,如果inputEnabled为false,在Update中将targetDirUp和targetDirRight设置为0。
// 模块软开关
public bool inputEnabled = true;
// Update is called once per frame
void Update()
{
// 将上下键的输入整合 计算向上方向的输入大小
targetDirUp =
((Input.GetKey(keyUp) ? 1.0f : 0) - (Input.GetKey(keyDown) ? 1.0f : 0));
// 将左右键的输入整合 计算向右方向的输入大小
targetDirRight =
((Input.GetKey(keyRight) ? 1.0f : 0) - (Input.GetKey(keyLeft) ? 1.0f : 0));
// 输入模块是否关闭 这段代码一定要2放在这个位置
if (!inputEnabled)
{
targetDirUp = 0;
targetDirRight = 0;
}
// ...
}
最后,还可以在输入模块中处理输入。
// 转换输入的坐标从方向到圆形
m_dirAxis = SquareToCircle(new Vector2(dirRight, dirUp));
// 计算输入模长
dirMag = Mathf.Sqrt(m_dirAxis.y * m_dirAxis.y + m_dirAxis.x * m_dirAxis.x);
// 计算玩家的方向
dirVec = m_dirAxis.x * transform.right + m_dirAxis.y * transform.forward;
这套方案貌似对手柄来说不是那么好用,而且可以直接使用GetAxis,再在Unity里面调InputManager就行了。
以后还会有更多输入相关代码加入进来。
关于Unity中定义的Key string名,可以查看网站:C# list of string name for Input.GetKey(string name)