在上文介绍的算法中,背景只在每次调用Update()时移动一次。这样一来,如果武士移动的距离很长,即速度很快,就可能出现背景和角色移动不协调的情况.虽然我们这个游戏中不会打到那样快的移动速度,但是有些游戏中出现过玩家校色移动,或者在场景中移动到错误位置的现象。下面就让我们来考虑一下这种情况的解决办法
一、稍作尝试
下列是摁下w键后向前突刺的代码
// 通过“W”键向前方大幅移动(用于调试)
#if UNITY_EDITORif(Input.GetKeyDown(KeyCode.W)) {Vector3 position = this.transform.position;position.x += 100.0f*FloorControl.WIDTH*FloorControl.MODEL_NUM;this.transform.position = position;}
结果是角色移动的距离太长,背景跟不上角色了
二、背景组件显示位置的良改
在上文中,我们提到了相同类型的背景组件的背景组件会按照“total_width=一个组件的宽度×组件数量(3个)”的间隔重复出现。也就是说,程序将从下列值中,初始位置、初始位置+total_width×1、初始位置+total_width×2、初始位置+total_width×3、初始位置+total_width×4......初始位置+total_width×n中选取一个最靠近武士坐标的值作为背景组件出现的位置。因此,质押求出上面的n的值,就可以确定背景应该出现的位置。
接下来,让我们看看改良后的FloorControl.Update方法
void Update()
{
float total_width = FloorControl.WIDTH*FloorControl.MODEL_NUM;Vector3 camera_position = this.main_camera.transform.position;float dist = camera_position.x - this.initial_position.x;// 模型出现在total_width 的整数倍位置// 用初始位置的距离除以整体背景的宽度,再四舍五入int n = Mathf.RoundToInt(dist/total_width);Vector3 position = this.initial_position;position.x += n*total_width;this.transform.position = position;
}
上述代码中,dist是武士的移动距离。将dist除以背景组件的整体宽度total_width后的结果赋值给n
n是整数,但是经触发求出的结果并不一定是整数,因此把结果代入n之前,需要现做四舍五入处理。如果只是简单地进行类型转换(cast),将直接舍去小数部分,务必注意这一点
使用四舍五入,是为了在舍去和进位两种情况中选取最靠近武士坐标的情况。
我们可以使用Mathf.RoundToInt方法来实现四舍五入。Mathf是Unity中的一个功能类。它含有很多剧本的数学计算功能。
还有一种实现四舍五入的方法:让数字加上0.5后再舍去小数部分。可以利用Mathf.FloorToInt方法舍去小数部分
Mathf.RoundToInt(dist/total_width); //四舍五入
Mathf.FloorToInt(dist/total_width+0.5f); //加上0.5后社区小数部分(效果等同于四舍五入)
使用RoundToInt和FloorToInt方法时,需要注意输入值为负数的情况。RoundToInt直接对绝对值进行操作,而FloorToInt则会连同符号判断数值大小
下面是Unity官网的解释
RoundToInt
返回舍入为最近整数的 /f/。
如果数字结尾是 .5,从而使它处于两个整数正中间(其中一个是偶数,另一个是奇数),则返回偶数。
FloorToInt
返回小于或等于
f
的最大整数。
在本游戏中,武士的坐标只取正数,由于即使武士会往相反的方向移动也要判定“更近的一段”,因此程序中使用的RoundToInt方法。反在某些游戏中,则可能需要找出“更靠近左边的一端”,这种情况下就应该使用FloorToInt方法。总之,我们应当依据不同的情况灵活选择最好的方法。