This project demonstrates an experiment in connecting a C++ application with Unity via shared memory.
The goal was to test whether vertex data of a Unity mesh could be updated in real time by another process, with a focus on efficiency and low overhead.
The experiment was successful - Unity’s mesh vertices were influenced directly by the C++ process, achieving good performance.
A C++ application creates and writes to a memory-mapped file:
// Create or open a shared memory region
hMapFile = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, mapName);
if (hMapFile == NULL) {
std::cerr << "Error creating/opening shared memory: " << GetLastError() << std::endl;
return 1;
}
// Map the shared memory region into the process's address space
LPVOID mappedMemory = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, size);
if (mappedMemory == NULL) {
std::cerr << "Error mapping shared memory: " << GetLastError() << std::endl;
CloseHandle(hMapFile);
return 1;
}
// Update the content
for (int i = 0; i < blocks; i++) {
if ((pData[i].x + pData[i].y + pData[i].z) != 0) {
pData[i].x = pData[i].x + (pData[i].x * amount);
pData[i].y = pData[i].y + (pData[i].y * amount);
pData[i].z = pData[i].z + (pData[i].z * amount);
}
}On the Unity side, the mesh is updated by reading from the same shared memory:
// Map the shared memory object into the process's address space
mappedMemory = mmap(IntPtr.Zero, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mappedMemory.ToInt64() == MAP_FAILED)
{
Console.WriteLine("Error mapping shared memory: " + Marshal.GetLastWin32Error());
Close();
return;
}
// Cast the shared memory pointer to the desired type using unsafe code
unsafe
{
var sharedDataArray = (MMVector*)mappedMemory;
for (var i = 0; i < numElements; i++)
{
sharedDataArray[i].x = originalVertices[i].x;
sharedDataArray[i].y = originalVertices[i].y;
sharedDataArray[i].z = originalVertices[i].z;
}
}✅ Unity mesh vertices updated in real time
✅ Minimal overhead - efficient data transfer
✅ Stable synchronization between the two processes
This confirms that shared memory is a lightweight and effective method for high-frequency inter-process communication.
- Low Latency → avoids serialization and network stack delays
- High Throughput → suitable for frequent, bulk updates (e.g., vertex arrays)
- Cross-Process → allows external programs to drive Unity’s visualization
This is a proof-of-concept experiment.
The approach was tested and shown to be successful and efficient, making it a strong candidate for further real-time integration experiments.