Unity中FPS波动影响行星重力模拟,如何用Time.deltaTime修复?
解决Unity恒星-行星重力模拟受帧率波动影响的问题
问题核心是Update()每帧执行,帧率变化会导致每帧的实际时间间隔不一致,直接添加力会让行星运动速度和帧数绑定,而非真实时间。以下是两种有效解决方法:
方案1:在Update()中加入Time.deltaTime
将计算出的力乘以Time.deltaTime,让力的作用效果和实际时间挂钩,不管帧率如何波动,每秒的速度变化量保持一致。
修改后的代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Attractor : MonoBehaviour { const float G = 667.4f; public Rigidbody star; public Rigidbody planet; void Update(){ Vector3 direction = star.position - planet.position; float distance = direction.magnitude; if (distance == 0f) return; float forceMagnitude = G * (star.mass * planet.mass) / Mathf.Pow(distance, 2); // 乘以Time.deltaTime,归一化每帧的力作用时间 Vector3 force = direction.normalized * forceMagnitude * Time.deltaTime; planet.AddForce(force); } }
方案2:改用FixedUpdate()执行物理计算
Unity的FixedUpdate()会以固定的时间间隔调用(默认0.02秒),不受帧率波动影响,是处理物理操作的标准方式。此时不需要手动添加Time.deltaTime,直接保留原力的计算逻辑即可。
修改后的代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Attractor : MonoBehaviour { const float G = 667.4f; public Rigidbody star; public Rigidbody planet; // 替换成FixedUpdate,专门处理物理更新 void FixedUpdate(){ Vector3 direction = star.position - planet.position; float distance = direction.magnitude; if (distance == 0f) return; float forceMagnitude = G * (star.mass * planet.mass) / Mathf.Pow(distance, 2); Vector3 force = direction.normalized * forceMagnitude; planet.AddForce(force); } }
优先推荐方案2,因为Unity物理引擎本身基于固定时间步长设计,用FixedUpdate()能让模拟更稳定准确。
内容的提问来源于stack exchange,提问作者Zacattack Space
相关产品推荐
相关产品推荐

