一、需求分析
先来简单的做一些动态准星调整的需求分析:
- 玩家闲置(idle)准心最小,表示此时拿枪最稳
- 玩家走动(walk)准心适当增大
- 跑动时(run)准心增大到最大
- 前3种情况下,都应实现,开枪时准心都应快速缩放。来增强射击手感
要注意的两点:
- 准心增大或缩小是一个过程,不能在一帧完成,要逐步分给十几帧完成。
- 在处于这三种状态之一时,如玩家持续处于该状态,则准心也因保持对应的开合状态。
二、思路
前1、2、3点需求
一个动作要分几帧来完成,一般都要用到协程,但会有两个问题: 1、在update函数中做玩家运动状态判断时,容易重复调用。 2、状态保持繁琐。 所以,可以换种思路,通过观察上诉三种状态。我们可以为其定义三种开合度。
- 闲置状态开合度:0
- 走:50
- 跑:100
上图为开合度变化的一种。可以让它逐渐趋于其中一个状态。通过修改其3种开合度,而不在指定的开合度则逐帧减少或增加开合度使其趋于
第4点需求
射击时,要使准心快速的缩放。只在射击时调用一次,且不需维持状态。可很方便的用协程来实现
三、实现
前1、2、3
可将总的实现步骤分两个层次
- 第一层:只负责判断是否要切换状态和若不在指定状态则调用第二层(逐帧调用)。
if (playerCrl.m_IsWalking && playerCrl.m_NoRunning)
{
ExpandingCrossUpdate(crossExpandDegrsee);
}
else if (playerCrl.m_IsWalking && !playerCrl.m_NoRunning)
{
ExpandingCrossUpdate(crossExpandDegree * 2f);
}
else
{
ExpandingCrossUpdate(0);
}
- 第二层,只负责以指定的步长增大或减少准心开会度(注意,在一帧内只被调用一次)
private void ExpandingCrossUpdate(float expandDegree)
{
if (currentExpandedDegree < expandDegree - 5)
{
ExpendCross(150 * Time.deltaTime);
}
else if (currentExpandedDegree > expandDegree + 5)
{
ExpendCross(-300 * Time.deltaTime);
}
}
private void ExpendCross(float add)
{
crossQuarterImgs[0].transform.localPosition += new Vector3(0, add, 0);
crossQuarterImgs[1].transform.localPosition += new Vector3(-add, 0, 0);
crossQuarterImgs[2].transform.localPosition += new Vector3(0, -add, 0);
crossQuarterImgs[3].transform.localPosition += new Vector3(add, 0, 0);
currentExpandedDegree += add;
}
第4
此协程可只负责瞬间增大准心。因为增大后的准心没有趋近与某个状态,上述方法可将括大的准心自动将其恢复。
private void shoot()
{
StartCoroutine(ShootRecoil_Cross());
}
private IEnumerator ShootRecoil_Cross()
{
for (int i = 0; i < 2; i++)
{
yield return null;
ExpendCross(Time.deltaTime * 500);
}
}
注意,上述的ExpendCross()中给的参数需经测试才能得到较好的结果。
四、效果
|