制作类Agario 2D游戏时多物体跟随相机抖动问题排查
解决Agario类2D游戏相机跟随抖动问题
相机抖动的核心原因通常是目标位置的帧间跳变或渲染层面的亚像素偏移,以下是针对性的修复方案:
常见问题点及修复步骤
1. 目标中心计算时机不匹配
如果游戏物体是通过Rigidbody2D物理驱动移动的,物理更新在FixedUpdate执行,原代码在LateUpdate实时计算中心会拿到滞后的物体位置,导致帧间跳变。
修复:在FixedUpdate中计算并缓存中心位置,避免实时计算的滞后:
private Vector3 cachedCenter; void Start() { if (objectsList.Count > 0) cachedCenter = GetCenterOfObjects(objectsList); } void FixedUpdate() { if (objectsList.Count == 0) return; Vector3 newCenter = GetCenterOfObjects(objectsList); // 对中心做二次平滑,避免单个物体突然移动导致中心跳变 cachedCenter = Vector3.Lerp(cachedCenter, newCenter, 0.1f); }
2. 亚像素渲染导致视觉抖动
2D游戏中,相机位置若未对齐整数像素,会触发亚像素渲染,出现模糊或抖动。
修复:相机位置更新后,强制对齐到像素网格(pixelsPerUnit需与Sprite设置一致):
void LateUpdate() { Vector3 targetPosition = new Vector3(cachedCenter.x, cachedCenter.y, -10); transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime); // 像素对齐 float pixelsPerUnit = 100f; // 替换为你项目的像素单位值 Vector3 alignedPos = transform.position; alignedPos.x = Mathf.Round(alignedPos.x * pixelsPerUnit) / pixelsPerUnit; alignedPos.y = Mathf.Round(alignedPos.y * pixelsPerUnit) / pixelsPerUnit; transform.position = alignedPos; }
3. SmoothDamp参数不合理
原代码smoothTime = 0.3f可能过大,导致相机响应滞后或摆动;过小则会过于灵敏。
修复:将smoothTime调整至0.1f~0.2f区间,根据实际手感微调。
4. 物体物理插值未开启
使用物理移动的物体,未开启插值会导致位置帧间跳变,带动相机抖动。
修复:选中带Rigidbody2D的物体,在Inspector面板将Interpolation设置为Interpolate。
完整修改后代码
using UnityEngine; using System.Collections.Generic; public class CameraFollow : MonoBehaviour { public List<Transform> objectsList; public float smoothTime = 0.15f; public float centerSmoothFactor = 0.1f; private Vector3 velocity = Vector3.zero; private Vector3 cachedCenter; void Start() { if (objectsList.Count > 0) cachedCenter = GetCenterOfObjects(objectsList); } void FixedUpdate() { if (objectsList.Count == 0) return; Vector3 newCenter = GetCenterOfObjects(objectsList); cachedCenter = Vector3.Lerp(cachedCenter, newCenter, centerSmoothFactor); } void LateUpdate() { Vector3 targetPosition = new Vector3(cachedCenter.x, cachedCenter.y, -10); transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime); // 像素对齐,适配2D渲染 float pixelsPerUnit = 100f; Vector3 alignedPos = transform.position; alignedPos.x = Mathf.Round(alignedPos.x * pixelsPerUnit) / pixelsPerUnit; alignedPos.y = Mathf.Round(alignedPos.y * pixelsPerUnit) / pixelsPerUnit; transform.position = alignedPos; } Vector3 GetCenterOfObjects(List<Transform> objects) { Vector3 sum = Vector3.zero; foreach (Transform obj in objects) { sum += obj.position; } return sum / objects.Count; } }
内容的提问来源于stack exchange,提问作者Yraiv
相关产品推荐
相关产品推荐

