Wondering if someone could please give me some help.
I have an IComponentData with 2 ints.
public struct TileBiomeComponent : IComponentData
{
public int IndexBiome;
public int IndexDataRow;
}
and in a system, I want to separate them out into 2 NativeArrays. Is there a way to use reinterpret to achieve this? I did a test with a single int and that seems to work but im not sure how to achieve the same with 2 int
Reinterpret do nothing for reorganize your memory layouts. Its just change type of pointer and nothing else. In your data layout your TileBiomeComponent in native array was stored like
IndexBiome | IndexDataRow | IndexBiome | IndexDataRow …
I can suggest (if you want process this fields in arrays) split your component to two components.
Ok ty , NativeSlice is what I was looking for. Just for my own education what the use case for reinterpret then. I thought it transforms your data type while copying it to a native array.
You can use Reinterpret if you want to use all bytes and Reinterpret them as a different type, where you Slice them if you want to use every n strided byte.
… and just to be precise: that answer was related to SliceWithStride, a Slice in general is like a view and it is also useful if you want to get a view on some subsection of an array. Together with stackalloc or allocation free utilities you can very efficiently “slice” an subarray out of an array and still pass it to a function that does something for every element of the input, without the called function to ever know that the actual array is larger.
Slice is slower than NativeArray for contiguous memory (since slice has the overhead of managing strides). If you need a contiguous sub-array, there’s GetSubArray. If you have some random bit of memory (eg stackalloced) that you want to present as a NativeArray, there’s ConvertExistingDataToNativeArray, which is a bit awkward to use with the safety system, but can be wrapped like this:
public static unsafe NativeArray<T> toNativeArray<T>(void* data, int elementCount) where T : struct
{
NativeArray<T> array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<T>(data, elementCount, Allocator.Invalid);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, AtomicSafetyHandle.GetTempUnsafePtrSliceHandle());
#endif
return array;
}
NativeSlice is made for exactly the situation that @francois85 is asking for – handling strided data.
EDIT: That latter technique is vital if you want to do anything moderately complex with BlobArrays (otherwise you’re passing “ref” everywhere and it gets incredibly awkward):
public static unsafe NativeArray<T> toNativeArray<T>(ref this BlobArray<T> ba) where T : struct
=> toNativeArray<T>(ba.GetUnsafePtr(), ba.Length);
public static unsafe NativeArray<T> toNativeArray<T>(ref this BlobArray<T> ba, int start, int length) where T : struct
{
if(start < 0 || start + length > ba.Length)
throw new IndexOutOfRangeException($"Slice [{start} .. {start + length}] is outside bounds of array [0 .. {ba.Length}]");
void* pStart = ba.GetUnsafePtr() + (start * UnsafeUtility.SizeOf<T>());
return toNativeArray<T>(pStart, length);
}