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

如何从Unity 1D NativeArray中高效提取指定矩形区域的数据

Unity NativeArray 矩形区域高效提取方案

实现原理

存储2D图像的一维NativeArray默认采用行优先的顺序排列元素,单个像素的索引计算公式为:原索引 = y * 原数组宽度 + x。
你要提取的矩形区域数据只有同行内的元素是连续的,跨行之间存在无效间隔,因此无法单次调用NativeArray<>.Copy完成提取,我们可以采用逐行复制的方案,既保留NativeArray.Copy的底层性能优势,又能匹配非连续块的提取需求。

具体实现步骤

  • 第一步:先做参数合法性校验,避免越界访问:
    • 校验x + 矩形宽度 <= 原数组宽度、y + 矩形高度 <= 原数组高度
    • 校验输入的NativeArray长度和原宽度*原高度一致
  • 第二步:初始化用于存储结果的NativeArray,长度为矩形宽度 * 矩形高度,根据使用场景选择合适的内存分配器(临时使用选Allocator.Temp,需要跨帧留存选Allocator.Persistent)
  • 第三步:遍历矩形的每一行,逐行调用NativeArray<>.Copy复制对应连续片段:
    1. 计算原数组当前行的起始索引:(y + 当前目标行号) * 原宽度 + x
    2. 计算目标数组当前行的起始索引:当前目标行号 * 矩形宽度
    3. 单次复制长度为矩形宽度

代码示例

using Unity.Collections;

/// <summary>
/// 从行优先存储的2D NativeArray中提取指定矩形区域
/// </summary>
/// <param name="source">原一维NativeArray</param>
/// <param name="srcWidth">原数组对应2D结构的宽度</param>
/// <param name="srcHeight">原数组对应2D结构的高度</param>
/// <param name="rectX">提取矩形左上角x坐标</param>
/// <param name="rectY">提取矩形左上角y坐标</param>
/// <param name="rectW">提取矩形宽度</param>
/// <param name="rectH">提取矩形高度</param>
/// <param name="allocator">结果数组的内存分配器类型</param>
/// <returns>存储提取结果的NativeArray,使用完毕需要手动Dispose</returns>
public static NativeArray<T> ExtractRectFromNative2D<T>(NativeArray<T> source, int srcWidth, int srcHeight, 
    int rectX, int rectY, int rectW, int rectH, Allocator allocator) 
    where T : struct
{
    // 参数校验
    if(source.Length != srcWidth * srcHeight)
        throw new System.ArgumentException("原数组长度和输入宽高不匹配");
    if(rectX <0 || rectY <0 || rectX + rectW > srcWidth || rectY + rectH > srcHeight)
        throw new System.ArgumentOutOfRangeException("提取矩形超出原数组范围");
    
    // 初始化结果数组
    var result = new NativeArray<T>(rectW * rectH, allocator);
    
    // 逐行复制
    for (int row = 0; row < rectH; row++)
    {
        int srcStartIdx = (rectY + row) * srcWidth + rectX;
        int dstStartIdx = row * rectW;
        NativeArray<T>.Copy(source, srcStartIdx, result, dstStartIdx, rectW);
    }

    return result;
}

示例验证

针对你给出的5x5数组、提取(x:2,y:1,w:3,h:2)的场景,调用上述方法的执行逻辑如下:

  • 第0行目标行:原数组起始索引为 1*5 +2 =7,复制3个元素(索引7、8、9)到结果数组索引0、1、2
  • 第1行目标行:原数组起始索引为 2*5 +2 =12,复制3个元素(索引12、13、14)到结果数组索引3、4、5
    最终得到的6个元素完全匹配矩形区域的要求。

注意事项

  • 该方案的性能接近单次全量Copy,因为逐行调用的NativeArray<>.Copy是底层直接内存拷贝实现,远高于逐像素循环赋值的效率,适合大规模数组的提取操作
  • 结果NativeArray使用完毕后必须调用Dispose()方法释放内存,避免Native内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:24:03