Unity URP中调整Depth Of Field焦距的脚本致编辑器无响应
Unity景深平滑调节脚本修复(解决编辑器冻结问题)
问题根源
你的unblur()方法里用了同步while循环,会在单帧内执行数万次迭代(当你把fadeRate除以1000时),直接阻塞Unity主线程,导致编辑器完全无响应。哪怕不除以1000,循环也会在几毫秒内完成——Unity渲染是每帧更新一次,单帧内的数值变化根本无法被肉眼捕捉,所以要么焦距跳变要么看起来没变化。
解决方案
用Unity的**协程(Coroutine)**实现逐帧(或按时间间隔)的平滑数值变化,让主线程有时间处理渲染和输入操作,既不会卡死编辑器,又能得到流畅的焦距过渡效果。
修改后的完整代码
using System.Collections; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class UnblurBackground : MonoBehaviour { public Volume vol; // 每秒增加的焦距值,直接在Inspector调整(比如设为0.5代表每秒增加0.5) public float fadeRatePerSecond = 0.5f; public float startFocusDistance = 0.1f; public float maxFocusDistance = 10f; private float focusDistance; DepthOfField dph; void Awake() { VolumeProfile volumeProfile = GetComponent<Volume>()?.profile; if (!volumeProfile) throw new System.NullReferenceException(nameof(VolumeProfile)); if (!volumeProfile.TryGet(out dph)) throw new System.NullReferenceException(nameof(dph)); // 初始化焦距 focusDistance = startFocusDistance; dph.focusDistance.Override(focusDistance); } // 协程实现平滑焦距增加 public IEnumerator UnblurCoroutine() { // 避免重复触发导致协程叠加 StopAllCoroutines(); while (focusDistance < maxFocusDistance) { // 按时间增量计算,保证不同帧率下速度一致 focusDistance += fadeRatePerSecond * Time.deltaTime; // 防止数值超过最大值 focusDistance = Mathf.Min(focusDistance, maxFocusDistance); dph.focusDistance.Override(focusDistance); // 等待下一帧再执行循环 yield return null; } } // 供UI按钮绑定的触发方法 public void StartUnblur() { StartCoroutine(UnblurCoroutine()); } // 测试用:启动时自动执行 void Start() { StartCoroutine(UnblurCoroutine()); } }
关键修改点
- 替换同步
while循环为协程,用yield return null让代码每帧执行一次,彻底避免主线程阻塞 - 用
fadeRatePerSecond * Time.deltaTime计算增量,保证在不同帧率下,焦距增加的速度完全一致 - 新增
maxFocusDistance变量替代硬编码数值,方便灵活调整 - 增加
StartUnblur()方法,可直接绑定到UI按钮的OnClick事件(在Inspector拖入脚本对象,选择该方法即可) - 添加
StopAllCoroutines()防止多次触发导致协程叠加,出现加速异常
使用说明
- 在Inspector面板调整
fadeRatePerSecond:数值越大,焦距增加速度越快 - 如果需要通过按钮触发,删除
Start()里的调用,将UI按钮的点击事件绑定到StartUnblur()方法即可
内容的提问来源于stack exchange,提问作者Braith
相关产品推荐
相关产品推荐

