You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中FixedUpdate过多else if导致帧率下降的优化咨询

嘿,我完全懂你现在的头疼事儿——40个else if堆在FixedUpdate里,不仅帧率掉得厉害,以后要加新状态或者改参数时,简直是给自己挖了个维护大坑!咱们来把这堆逻辑重构得既高效又好维护,给你几个实用的方案:

方案1:枚举+配置数组(最直观,新手友好)

这是最容易上手的方案,把所有相机状态先定义成枚举,然后用一个数组存每个状态对应的offset参数,不用一堆判断,直接根据当前状态取配置就行。

步骤1:定义状态枚举和配置结构体

先在脚本里加个枚举,对应你原来的manjat、manjat2这些状态:

// 定义相机状态枚举
private enum CameraState
{
    Normal, // 默认状态
    Manjat,
    Manjat2,
    Manjat4,
    Manjat5
    // 其他40个状态依次加在这里
}

// 定义状态对应的配置结构体
[System.Serializable]
private struct CameraOffsetConfig
{
    public CameraState state;
    public Vector3 offset;
}

步骤2:在Inspector里配置参数

在脚本里加一个可序列化的数组,这样你直接在Unity编辑器里就能拖放配置,不用改代码:

public CameraOffsetConfig[] offsetConfigs; // 在Inspector里配置每个状态对应的offset
private CameraState currentState;
private Vector3 currentOffset; // 缓存当前offset,不用每次都查

步骤3:初始化+状态切换逻辑

在Awake或者Start里先把默认offset设好,然后不要在FixedUpdate里判断状态——而是在状态变化的时候(比如PisauScript.nonaktifkamera里的变量改变时)更新currentState和currentOffset:

private void Awake()
{
    // 初始化默认offset
    currentOffset = offset;
}

// 写一个专门更新状态的方法,不要在FixedUpdate里做判断!
public void UpdateCameraState()
{
    // 这里替换成你原来的状态判断逻辑,但只在状态变化时执行
    if (PisauScript.nonaktifkamera.manjat)
    {
        SetCameraState(CameraState.Manjat);
    }
    else if (PisauScript.nonaktifkamera.manjat2)
    {
        SetCameraState(CameraState.Manjat2);
    }
    // ...其他状态判断
    else
    {
        SetCameraState(CameraState.Normal);
    }
}

// 真正设置状态的方法
private void SetCameraState(CameraState newState)
{
    if (currentState == newState) return; // 状态没变化就直接返回,避免重复操作
    currentState = newState;
    // 从配置数组里找对应的offset
    foreach (var config in offsetConfigs)
    {
        if (config.state == newState)
        {
            currentOffset = config.offset;
            break;
        }
    }
}

步骤4:简化FixedUpdate

现在FixedUpdate里就不用一堆判断了,直接用缓存的currentOffset:

private void FixedUpdate()
{
    Vector3 desiredPosition = target.position + currentOffset;
    Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
    transform.position = smoothedPosition;
}
方案2:字典映射(查找速度更快)

如果状态特别多(40个),用数组遍历还是有点慢,那可以把配置数组转成字典,查找时间是O(1),更高效:

修改初始化和SetCameraState方法

private Dictionary<CameraState, Vector3> offsetDict;

private void Awake()
{
    currentOffset = offset;
    // 把配置数组转成字典
    offsetDict = new Dictionary<CameraState, Vector3>();
    foreach (var config in offsetConfigs)
    {
        offsetDict[config.state] = config.offset;
    }
}

private void SetCameraState(CameraState newState)
{
    if (currentState == newState) return;
    currentState = newState;
    // 直接从字典取,比遍历数组快多了
    if (offsetDict.TryGetValue(newState, out Vector3 newOffset))
    {
        currentOffset = newOffset;
    }
    else
    {
        // 没有找到对应状态时用默认值
        currentOffset = offset;
    }
}
方案3:状态模式(适合未来有复杂逻辑扩展)

如果以后每个相机状态不止改offset,还要加其他逻辑(比如切换相机FOV、开启特效),那状态模式更合适,每个状态对应一个类,职责更清晰:

步骤1:定义状态接口

private interface ICameraState
{
    Vector3 GetOffset();
    // 可以加其他方法,比如void EnterState()、void UpdateState()等
}

步骤2:实现每个状态类

private class ManjatState : ICameraState
{
    public Vector3 GetOffset()
    {
        return new Vector3(-5, 14, 6);
    }
}

private class Manjat2State : ICameraState
{
    public Vector3 GetOffset()
    {
        return new Vector3(-14, 25.5f, 6);
    }
}
// 其他状态类依次实现...

步骤3:管理状态切换

private ICameraState currentState;

private void Awake()
{
    // 默认状态
    currentState = new NormalState();
}

public void UpdateCameraState()
{
    if (PisauScript.nonaktifkamera.manjat)
    {
        currentState = new ManjatState();
    }
    else if (PisauScript.nonaktifkamera.manjat2)
    {
        currentState = new Manjat2State();
    }
    // ...其他状态切换
    else
    {
        currentState = new NormalState();
    }
}

private void FixedUpdate()
{
    Vector3 desiredPosition = target.position + currentState.GetOffset();
    Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
    transform.position = smoothedPosition;
}
额外优化小技巧
  • 不要在FixedUpdate里访问静态变量:把PisauScript.nonaktifkamera缓存成一个局部变量,比如在Awake里private NonaktifKamera kameraRef = PisauScript.nonaktifkamera;,避免每次都查找静态变量。
  • 状态变化才更新:不要每一帧都判断40个状态,而是在PisauScript.nonaktifkamera里的变量变化时(比如用事件通知),再调用UpdateCameraState,这样FixedUpdate里完全没有判断逻辑,帧率提升更明显。

内容的提问来源于stack exchange,提问作者Kira Angelic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:52:31