2D游戏的开发中,时常在测试时会注意到轻微的抖动,特别当玩家停止走动并且虚拟相机因为阻尼缓缓停止跟随时,此现象尤为明显。究其原理是虚拟摄像机太灵敏所致,获得最终位置数据常常带有小数点后的子像素,进而无法对标以像素为单位的地图。我们将创建一个名为RoundCameraPos的C#脚本,以将虚拟摄像机最终坐标舍入为与PPU对齐的值:

  

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//导入Cinemachine框架,以调用相关组件
using Cinemachine;

//要附加到Chinemachine的处理管道上的框架必由CinemachineExtension继承
public class RoundCameraPos : CinemachineExtension
{
//每世界单位单位像素占32
public float PixelsPerUnit = 32;

//由CinemachineExtension继承的类均需调用此方法,用以被Chinemachine Confiner(边界)处理后,再由Cinemachine调用
protected override void PostPipelineStageCallback(CinemachineVirtualCameraBase vcam,
CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
{
//虚拟摄像机后期处理到了BOdy阶段时,可以设置虚拟摄像机在space中位置
if (stage == CinemachineCore.Stage.Body)
{
//获取虚拟摄像机最终位置
Vector3 pos = state.FinalPosition;
//用Round方法处理位置值后,创建一个新的对齐了像素的Vertor。
Vector3 pos2 = new Vector3(Round(pos.x), Round(pos.y), pos.z);
//将虚拟摄像机最终位置设为Round方法处理后位置和老位置差值,减小误差
state.PositionCorrection += pos2 - pos;
}
}


float Round(float x) {
//四舍五入之下使得摄像机对标单位为像素,而非子像素(舍入成为与PPU对齐的值而不带小数,防止过于精确而产生停止跟随时的抖动)
return Mathf.Round(x * PixelsPerUnit) / PixelsPerUnit;
}

 posted on 2021-03-25 13:52  雨落江州  阅读(693)  评论(0编辑  收藏  举报