赞
踩
在游戏开发中时常会用到摄像机跟随的技术,有些项目还对Time.scale做更改,以达到时间缩放的效果(子弹时间),让人头疼的是,游戏画面总会时不时的抖动.接下来我就来说说解决摄像机抖动的思路和方法.
//TODO
public class CameraFallow : MonoBehaviour//摄像机脚本 { Transform target;//目标 Vector3 offPos;//位置偏差 void Start() { target = GameObject.Find("Sphere").transform; offPos = transform.position - target.position;//从目标指向摄像机的向量 } void Update() { transform.position = target.position + offPos;//跟随目标 } }
public class CubeMove : MonoBehaviour//方块移动脚本
{
void Update()
{
this.transform.Translate(0, 0, 10 * Time.deltaTime);//每秒10米
}
}
问题演示图
想要的效果演示图
确信一点: 画面抖动的原因是因为摄像机位置更新与目标(抖动对象)位置更新不同步造成的.
为什么会不同步呢这就涉及到unity生命周期函数执行顺序问题以及物理帧与渲染帧的问题.
做摄像机跟随是常用的功能,一般来说,将摄像机的位置,插向目标位置即可实现。
有时候需要摄像机起初不跟随,当目标快要越出屏幕时再开始跟随,这时,应着重考虑两者的偏差值。
public class CameraFollow : MonoBehaviour { GameObject target; Vector3 p0;//起始位置 Vector3 p1;//目标临界位置 Vector3 pd;//偏差 void Start() { target = GameObject.Find("Bison"); p0 = transform.position; p1 = new Vector3(-5, 1.5f, 0); } void FixedUpdate() { if (BisonController.Instance.isOverUp)//达到临界值 { pd = p1 - p0; transform.position = Vector3.Lerp(transform.position, target.transform.position - pd, 0.5f);//将摄像机的位置插向目标减去偏差的那个位置,而不是目标位置本身。 } else { transform.position -= new Vector3(0, 0.05f, 0);//当目标低于临界值, 摄像机逐渐回到起初的位置 if (transform.position.y <= 0.2f) { transform.position = p0; } } } }
抖动问题,很多时候做主角和背景(场景)的移动方式不一样, 主角用 物理引擎,而背景为渲染帧变换, 在默认情况下,两者的时间间隔是不一致的, 物理帧为0.02s,而渲染帧和设备有很大关系,在流畅的情况下约为0.01666666s ,所以如果 主角和背景分别采用不同的方式移动,那两者的移动步调是不一致的。摄像机跟随,如果写在FixedUpdate里面,是采用的物理帧,就会和角色同步,但和背景不同步,容易出现屏幕抖动的状况。 如果写在Update或是LateUpdate里面,都是渲染帧,这时和背景的步调是一致的,但和主角移动不一致,就会出现,主角抖动的现象。
要解决这位问题,可以从两个思维解决, ①将物理帧时间和渲染帧时间调得相同 ②设计功能时角色及背景都采用同一种模式,要不都用渲染帧要不都用 物理帧
我在开发功能的时候,由于 角色的功能很难不采用物理引擎,需要用到 rigidbody.velocity ,我使用了第一种方式,将物理帧时间调至0.016666s,避免了 抖动的情况。当然这只是一种规避的补救措施,如果后续出现大量资源调用,等一些需求, 可能抖动又会出现。 介于目前能力,只能先这样解决。若后续有机会,再做其它尝试。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。