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

Unity C#类Minecraft项目区块边界立方体优化的冗余代码问题

区块立方体优化方法冗余消除方案

1. 抽离公共判断逻辑

先把“判断立方体是否被完全包围”的核心逻辑单独封装成独立方法,这是两个原方法共用的核心,抽离后彻底避免重复代码:

// 预定义六个方向向量,避免重复写硬编码值
private readonly Vector3[] _surroundingDirs = {
    Vector3.up, Vector3.down, Vector3.forward,
    Vector3.back, Vector3.right, Vector3.left
};

// 公共判断方法:输入立方体位置和区块上下文,返回是否被完全包围
private bool IsCubeFullySurrounded(Vector3 cubePos, ChunkContext context)
{
    foreach (var dir in _surroundingDirs)
    {
        // 替换成你原方法中检查对应方向是否有方块/区块的逻辑
        if (!CheckBlockExists(cubePos + dir, context))
        {
            return false;
        }
    }
    return true;
}

2. 用回调分离差异行为

两个方法的核心差异在于判断后的动作:一个是跳过实例化,一个是禁用已存在的立方体。用委托(回调)把动作逻辑抽出来,写一个通用处理方法:

// 通用处理方法:传入判断所需参数,以及两种状态下的动作
private void ProcessCube(Vector3 cubePos, ChunkContext context, Action onSurrounded, Action onExposed = null)
{
    bool isSurrounded = IsCubeFullySurrounded(cubePos, context);
    if (isSurrounded)
    {
        onSurrounded?.Invoke();
    }
    else
    {
        onExposed?.Invoke();
    }
}

// 处理新区块立方体:被包围则跳过实例化,否则创建
private void HandleNewChunkCube(Vector3 cubePos, ChunkContext context)
{
    ProcessCube(cubePos, context,
        onSurrounded: () => { /* 空实现,直接跳过实例化 */ },
        onExposed: () => { InstantiateCube(cubePos, context); }
    );
}

// 处理邻接区块立方体:被包围则禁用,否则启用
private void HandleAdjacentChunkCube(GameObject cube, ChunkContext context)
{
    Vector3 cubePos = cube.transform.position;
    ProcessCube(cubePos, context,
        onSurrounded: () => { cube.SetActive(false); },
        onExposed: () => { cube.SetActive(true); }
    );
}

3. 泛型的合理使用场景

如果你的两个方法操作的对象类型不同(比如一个是预制体,一个是已实例化的Cube对象),可以用泛型约束统一方法签名,但泛型只解决类型重复问题,核心差异还是靠回调处理:

// 泛型版通用处理方法,约束对象为Unity的Object类型
private void ProcessCube<T>(T cubeObj, Vector3 cubePos, ChunkContext context, Action<T> onSurrounded, Action<T> onExposed = null)
    where T : UnityEngine.Object
{
    bool isSurrounded = IsCubeFullySurrounded(cubePos, context);
    if (isSurrounded)
    {
        onSurrounded?.Invoke(cubeObj);
    }
    else
    {
        onExposed?.Invoke(cubeObj);
    }
}

// 调用示例:处理预制体
ProcessCube(cubePrefab, cubePos, context,
    onSurrounded: (_) => { /* 跳过实例化 */ },
    onExposed: (prefab) => { Instantiate(prefab, cubePos, Quaternion.identity); }
);

// 调用示例:处理已存在的立方体
ProcessCube(existingCube, cubePos, context,
    onSurrounded: (cube) => { cube.SetActive(false); },
    onExposed: (cube) => { cube.SetActive(true); }
);

4. 额外精简技巧

如果需要反向判断(比如检查是否未被包围),给IsCubeFullySurrounded加一个可选参数实现结果反转,避免重复写反向逻辑:

private bool IsCubeFullySurrounded(Vector3 cubePos, ChunkContext context, bool invertResult = false)
{
    bool isSurrounded = true;
    foreach (var dir in _surroundingDirs)
    {
        if (!CheckBlockExists(cubePos + dir, context))
        {
            isSurrounded = false;
            break;
        }
    }
    return invertResult ? !isSurrounded : isSurrounded;
}

学习方向建议

  • 重点掌握封装与抽象:学会拆分代码中的“可变部分”和“不变部分”,把不变逻辑封装,可变逻辑抽象成接口或委托。
  • 理解策略模式:这是处理“同逻辑不同行为”场景的经典方案,用委托就能轻量实现,无需复杂框架。
  • 泛型进阶:明确泛型的核心作用是解决类型重复问题,不要用泛型处理行为差异,行为差异交给回调或策略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 08:02:32