I try to stream the desktop of a Computer ingame onto a plane in Unity3D (and later interacting with it). I got to work the screencapturing, but already after a minute the unity game just fills the RAM of my PC (~30GB).
I already try to clean it by calling the Garbage Collector manually, but calling it doesn't seem to change anything.
I also wrote a test application in native C# in Visual Studio with Windows Forms. In the C# test application the code behaves all good and doesn't flood the RAM.
Is there a possibility, that Unity doesn't know how to free RAM? To get this code working I had to add the System.Drawing.dll
to my Unity game.
If this approach is not working, are there any other options to stream the desktop and show it on a plane in Unity?
Here is my current code:
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using UnityEngine;
public class ScreenCap : MonoBehaviour {
public Renderer renderer;
public MemoryStream stream;
// Use this for initialization
void Start () {
renderer = GetComponent<Renderer>();
startScreenCaptureThread();
}
// Update is called once per frame
void Update () {
Texture2D tex = new Texture2D(200, 300, TextureFormat.RGB24, false);
if (stream != null)
{
tex.LoadImage(stream.ToArray());
renderer.material.mainTexture = tex;
stream.Dispose();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
}
public void startScreenCaptureThread()
{
Thread t = new Thread(ScreenCapture);
t.Start();
}
public void ScreenCapture()
{
Rectangle screenSize;
Bitmap target;
MemoryStream tempStream;
while (true)
{
System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess();
Debug.Log(proc.PrivateMemorySize64);
screenSize = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
target = new Bitmap(screenSize.Width, screenSize.Height);
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(target))
{
g.CopyFromScreen(0, 0, 0, 0, new Size(screenSize.Width, screenSize.Height));
}
tempStream = new MemoryStream();
target.Save(tempStream, ImageFormat.Png);
tempStream.Seek(0, SeekOrigin.Begin);
stream = tempStream;
target.Dispose();
tempStream.Dispose();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
}
}