【发布时间】:2017-05-26 10:10:49
【问题描述】:
我尝试将计算机游戏的桌面流式传输到 Unity3D 中的平面上(然后与它进行交互)。我开始进行屏幕捕捉,但一分钟后,Unity 游戏已经填满了我 PC 的 RAM (~30GB)。
我已经尝试通过手动调用垃圾收集器来清理它,但调用它似乎并没有改变任何东西。
我还使用 Windows 窗体在 Visual Studio 中使用本机 C# 编写了一个测试应用程序。在 C# 测试应用程序中,代码运行良好,不会溢出 RAM。
是否有可能,Unity 不知道如何释放 RAM?为了让这段代码正常工作,我必须将System.Drawing.dll 添加到我的 Unity 游戏中。
如果这种方法不起作用,是否还有其他选项可以流式传输桌面并将其显示在 Unity 的平面上?
这是我当前的代码:
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();
}
}
}
【问题讨论】:
-
您可以尝试将 Texture2D、Rectangle、Bitmap 和 MemoryStream 变量的初始化移出方法。我也不确定 Unity 中的线程。我认为使用协程会更好。
-
我正在尝试在我的 VR 项目中添加一个虚拟桌面,发现使用 CopyFromSreen 在性能方面表现不佳,最高为 30fps,充分利用了 1 个 CPU 内核。看起来更好的方法是使用像 SharpDX 这样的 DirectX 库,或者像 github.com/Phylliida/UnityWindowsCapture 这样的东西(还不知道它是如何工作的)
标签: c# unity3d garbage-collection screen-capture