Performance Problem when running multiple Unity applications Embeded in WPF

Hi, I’m developing an application where I need to use Unity as a graphical engine to pre-visualise data in my DB.

I’m building my main application in WPF.
Through this link you can download my sample application: Dropbox - File Deleted - Simplify your life

Just go to VS Project\teste 2.sln, open it in Visual Studio and click Start.
You will see a huge performance drop, if I have 2 or more Unity instances running simultaneously.

I’d like to know why this is happening and sugestions on how to solve it.

Well… I’m not downloading your app.

But I can think of a few things.

  1. the big thing… you’re running 2 instances of the game. Games take a lot of resources, so you just ask for twice the amount of resources.

  2. I don’t know how you’re rendering the game in side your WPF application. Are you rendering to some WPF canvas or something? This would mean you’re probably hooking into the graphics pipeline and redirecting it to draw into WPF. This can come with HUGE caveats depending on how you do it… does it hook in and draw via the GDI api? Cause that is a notoriously slow process. Are you pre-capturing or post-capturing… in that are you allowing Unity to process on its own work and then just copying the graphics, or are you haulting the graphics process and forcing Unity to let your WPF app draw the graphics to its canvas? These sorts of things can cause the app to become tethered to your WPF apps process, and throttle things.

Also… why are you using Unity3D mixed with WPF? That’s just weird…

If I run 2 or more applications, there is minimal impact in the the amount of resources (they are very lightweight). The problem comes when I attach/embed those applications in WPF.

I know its weird but its better then developing my own 3d engine. I “just attach” the Unity(s) application(s) to my border control in wpf and render it borderless. I have no ideia if I’m redirecting the graphics pipeline or anything else. Unfortunatly, I’m not knowledgeable enough to asnswer what you are asking. But I’m going to research it now, and hopefully come back later and edit this post.

What are you using to run the application in WPF?

What is “just attach”?

It would be alot easyer if you looked at the example project I posted.
In WPF, in the Window_Loaded event, I start a new process (https://msdn.microsoft.com/en-us/library/system.diagnostics.process(v=vs.110).aspx?f=255&MSPPError=-2147217396). I just give it the Unity app path location, give it some command line params and Unity loads up, embeded in my WPF :slight_smile:

Dude, I’m not keen to go digging through your code. For many reasons including I don’t want to spend that time, I have my own time. And also, I don’t know who you are, or what your software is… it’s considered uncouth to have people download your raw code, since raw code can easily contains malicious stuff.

Just copy paste the line where you “embed it in your WPF”. Just using the Process class does not embed it in your app, it just starts up a process of any sort.

What are you doing to embed it?

process = new Process();
            process.StartInfo.FileName = _unityPath;
            process.StartInfo.Arguments = "-parentHWND " + hwndHost + " " + Environment.CommandLine;
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.CreateNoWindow = true;

            process.Start();

            process.WaitForInputIdle();

“hwndHost” is the control handle (in this case, a border control).

This is how I embed Unity withing my WPF (+/-)

OK, so you use the unity built-in ‘-parentHWND’ argument to tell unity where to draw to.

I personally don’t know in what way they implement this under the hood. But whatever way it is, it’s getting bottlenecked somewhere, which is hurting your performance. That bottleneck is probably caused by probably some need to wait on WPF for something, or vice versa.

Can implement some kind of Windows message monitoring in your application?
My blind guess would be that your application window forwards some messages to embedded Unity windows and something stalls when you have more than one embedded.

As far as I know, I’m sending 1 message per embeded Unity (so, in this case, 2 messages, 1 for each Unity). If there are more messages going out, I’m not aware of them.
Would it help if I posted my entire WPF class? I didn’t want to do that to not fill up the post with code

I mean not the messages that you send yourself, but all the messages sent to your windows window procedure. I think some of the messages that arrive to your windows procedure might be forwarded to Unity windows or your windows procedure get some notifications from something that happens in Unity windows. Just try logging everything in your windows proc with timestamps and then try to narrow down. Maybe this will help to pinpoint the cause.

I don’t know nearly enough about your app (also not downloading it), but supporting D3D in WPF (and making it fast) is not trivial.

The best I can offer right now is… have you looked into the D3DImage class in WPF? Are you rendering to that?

Ultimately it was key to getting fast 3D in WPF (for me), but that was back when Windows 7 was still the primary operating system, so my knowledge may be outdated.

I have no ideia what messages or messaging system you are refering to. Could you be more specific please?

Been at it for a few hours now but can’t seem to get it to work. Going to give it a few more tries but I’m not having high hopes :S

Windows messages.
Every window in Windows operating system has a registered Window Procedure, which receives a message for everything that happens in that window.
I suppose it’s worth creating a Win32 application with a window embedding 2 Unity instances. There you’d have a custom window procedure that you can modify any way you want.

Unity won’t allow me to listen for incoming messages.
I’ll try to listen for outgoing messages to Unity

Better create Win32 application for that. We’re trying to figure out why it slows down.

1 Like

Hello,
I have exactly same problems. I’ve written simple WinForms application:
-two panels on form
-each panel is embedded Unity process, embedding is done with this code snippet (got this from Unity’s EmbeddedWindow.zip example):

process1 = new Process();
process1.StartInfo.FileName = "Child.exe";
process1.StartInfo.Arguments = "-parentHWND " + panel1.Handle.ToInt32() + " " + Environment.CommandLine;
process1.StartInfo.UseShellExecute = true;
process1.StartInfo.CreateNoWindow = true;
process1.Start();
process1.WaitForInputIdle();
//and for process2 same as above with panel2

If I have one embedded Unity process everything works fine, but if I enable second embedded Unity process my WinForms app gets really laggy and unresponsive, but both Unity embedded process works still fine.

It’s crucial functionality for my application, so I hope it can be resolved somehow.

EDIT: I’m using Unity 2017.3.1f1