How to use shared memory in Unity ?
Hello, I want to use shared memory in Unity. I create flight Simulator.
Here system idea:
process A: Calculate x,y,z position of air plane, and send position data to shared memory. (Language is C++, C#...?)
unity process: Get position data from shared memory, and translate air plane by new positon data.
processA -> sharedMemory -> Unity
I don't know that Unity can use shared memory, or comunicate to any process.
Please help me!
Answer by Batlad · Oct 12, 2016 at 12:20 AM
@Kei_Jin I recently had to solve a similar issue myself.
I was using input from a custom USB controller so I had c++ code to handle its input. I created a shared memory location in a c++ program, I used CreateFileMapping since it is stored in ram and so gives the fastest refresh rate. The guides recommend using the global namespace, but that did not work for me, and simply removing it did work.
You will then need to read from that memory address in c#, this is a little complicated as you have to use unsafe code and pinvokes. Also unity will crash if you ever try to access the pointers but they haven't successfully accessed the memory yet, so be sure to save the project before any testing.
As for transforming your data, just make sure you use the equivalent datatypes on both ends and use Marshal functions to access it. In your case maybe three floats would be best. You may need to cast them from int if there are no marshall float functions.
Useful links: http://pinvoke.net/default.aspx/kernel32/OpenFileMapping.html https://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx
See code snippetts below for details.
c++ Code:
//For shared memory with Unity
#define BUF_SIZE 256
TCHAR szMapName[] = TEXT("UnityFileMappingObject");
TCHAR szCountName[] = TEXT("UnityFileCountObject");
signed int sharedMemOut[7];
LPCTSTR pBuf;
HANDLE hMapFile;
Init(){
// Request shared memory from the OS to share with Unity
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
BUF_SIZE, // maximum object size (low-order DWORD)
szMapName); // name of mapping object
if (hMapFile == NULL)
{
printf(TEXT("Could not create file mapping object (%d).\n"),
GetLastError());
return -1;
}
pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
printf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
CloseHandle(hMapFile);
return -1;
}
}
Update(){
sharedMemOut[0] = (int)count;
sharedMemOut[1] = X[0];
sharedMemOut[2] = Y[0];
sharedMemOut[3] = X[1];
sharedMemOut[4] = Y[1];
sharedMemOut[5] = SQ[0];
sharedMemOut[6] = SQ[1];
CopyMemory((PVOID)pBuf, sharedMemOut, (7 * sizeof(signed int)));
}
c# unity code:
using UnityEngine;
using System.Collections;
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
public class PlaneController: MonoBehaviour {
//Shared Memory
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern SafeFileHandle OpenFileMapping(
uint dwDesiredAccess,
bool bInheritHandle,
string lpName);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr MapViewOfFile(
SafeFileHandle hFileMappingObject,
UInt32 dwDesiredAccess,
UInt32 dwFileOffsetHigh,
UInt32 dwFileOffsetLow,
UIntPtr dwNumberOfBytesToMap);
/*
[DllImport("kernel32.dll", SetLastError = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
*/
string szMapName = "UnityFileMappingObject";
const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
const UInt32 SECTION_QUERY = 0x0001;
const UInt32 SECTION_MAP_WRITE = 0x0002;
const UInt32 SECTION_MAP_READ = 0x0004;
const UInt32 SECTION_MAP_EXECUTE = 0x0008;
const UInt32 SECTION_EXTEND_SIZE = 0x0010;
const UInt32 SECTION_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SECTION_QUERY |
SECTION_MAP_WRITE |
SECTION_MAP_READ |
SECTION_MAP_EXECUTE |
SECTION_EXTEND_SIZE);
const UInt32 FILE_MAP_ALL_ACCESS = SECTION_ALL_ACCESS;
private SafeFileHandle sHandle;
private IntPtr hHandle;
private IntPtr pBuffer;
private int sharedInputCount;
bool attachSuccessful;
//
int count;
int X0;
int Y0;
int X1 = -1;
int Y1 = -1;
int SQ0 = -1;
int SQ1 = -1;
void Start (){
sHandle = new SafeFileHandle(hHandle, true);
sharedInputCount = 0;
attachSuccessful = Attach(szMapName, 256);
}
unsafe public bool Attach(string SharedMemoryName, UInt32 NumBytes)
{
if (!sHandle.IsInvalid) return false;
sHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, SharedMemoryName);
Debug.Log("Shared mem open: ");
if (sHandle.IsInvalid) return false;
Debug.Log("Shared mem open SUCCESS: ");
pBuffer = MapViewOfFile(sHandle, FILE_MAP_ALL_ACCESS, 0, 0, new UIntPtr(NumBytes));
Debug.Log("Shared mem mapped: ");
return true;
}
unsafe public void Detach()
{
if (!sHandle.IsInvalid && !sHandle.IsClosed )
{
//CloseHandle(hHandle); //fair to leak if can't close
sHandle.Close();
}
pBuffer = IntPtr.Zero;
//lBufferSize = 0;
}
void Update()
{
if (!attachSuccessful)
{
attachSuccessful = Attach(szMapName, 256);
return;
}
}
void OnApplicationQuit()
{
if (attachSuccessful)
{
Detach();
}
}
void FixedUpdate ()
{
//get Shared memory Input
if (!attachSuccessful)
{
return;
}
count = Marshal.ReadInt32(pBuffer, 0);
X0 = Marshal.ReadInt32(pBuffer, 4);
Y0 = Marshal.ReadInt32(pBuffer, 8);
X1 = Marshal.ReadInt32(pBuffer, 12);
Y1 = Marshal.ReadInt32(pBuffer, 16);
SQ0 = Marshal.ReadInt32(pBuffer, 20);
SQ1 = Marshal.ReadInt32(pBuffer, 24);
}
}
I hope that puts you on the right track.
Very interesting. I will bookmark this for later use :)
Thanks for sharing!
Thank you! I try it, I can connect legacy system. Very very Thanks!
it works great for about 2$$anonymous$$ and then starts lagging on the unity side. did you have this problem as well ?
$$anonymous$$y implementation makes controller lag impossible to detect, because my c program stores the exact 2D location and feeds it to the unity program. So even if there's lag the next update will still put the player in the right location. If you mean whole program lag and fps loss, I'm not sure. I've never noticed this but I haven't run it intensively, (we're still waiting on some more hardware for the full application). But I'll try to do this the next chance I get.
Answer by ljhvr01 · Dec 27, 2016 at 04:44 AM
Hello Thank you for a good example.
But, Would I able to ask sample unity project for shared memory?
I can't clearly understand how it works in Unity
Answer by noer3364 · Jan 26, 2021 at 05:55 AM
Have you solved the problem? I have no problem with the way upstairs at windows PC,but how to deal with Android and IOS?
Your answer
![](https://koobas.hobune.stream/wayback/20220612093701im_/https://answers.unity.com/themes/thub/images/avi.jpg)