Is it possible to run several unity apps from UWP project code?
I mean that I have Unity project builded as UWP application, and I want to use Unity application as a control several time, in different pages.
I have two problems:
I can’t reset SwapChainPanel, when I do SetSwapChainPanel second time I get empty space in place whe should be Unity frame.
I don’t know and can’t find the answer can I run Unity app two times at the same time and use two unity frames in one UWP page or not?
If somebody can solve my problems It would be great.
Thanks!
You cannot run Unity app twice at the same time. You can, however, unload a Unity app using “Application.Unload()” and then initialize it from scratch again (recreating AppCallbacks, etc).
Yes, sure.
Version of unity: 2018.2.11f1.
With exception I have problem, I can’t see what exception exactly I have. Visual studio just suggest me open different visual studio, but even after this I don’t see details of exception.
Code below.
Unity script:
using UnityEngine;
using Application = UnityEngine.Application;
public class CubeBehaviourScript : MonoBehaviour
{
private static bool _isNeedUnload;
private static RotationDirection _direction;
public static void UnloadApplication()
{
_isNeedUnload = true;
}
// Use this for initialization
void Start()
{
_isNeedUnload = false;
}
// Update is called once per frame
void Update()
{
if (_isNeedUnload)
{
_isNeedUnload = false;
Application.Unload();
}
}
}
App.xaml.cs:
using Windows.ApplicationModel.Activation;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Unity;
using UnityPlayer;
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
namespace Cube
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
public static AppCallbacks AppCallbacks;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
InitializeComponent();
SetupOrientation();
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
InitializeUnity(args.Arguments);
}
private void InitializeUnity(string args)
{
AppCallbacks = new AppCallbacks();
ApplicationView.GetForCurrentView().SuppressSystemOverlays = true;
AppCallbacks.SetAppArguments(args);
var rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null && !AppCallbacks.IsInitialized())
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
#if !UNITY_HOLOGRAPHIC
Window.Current.Activate();
#endif
rootFrame.Navigate(typeof(StartPage));
}
// Setup scripting bridge
var bridge = new WinRTBridge.WinRTBridge();
AppCallbacks.SetBridge(bridge);
AppCallbacks.InitializeD3DXAML();
AppCallbacks.SetCoreWindowEvents(Window.Current.CoreWindow);
Window.Current.Activate();
// I have exception after this point
}
public static void ReInitializeUnity()
{
CubeBehaviourScript.UnloadApplication();
// This we need some delay, actualy I do "UnloadApplication" on button click and then ReInitializeUnity() on click of other button
((App) Current).InitializeUnity(string.Empty);
}
private void SetupOrientation()
{
UnityGenerated.SetupDisplay();
}
}
}
If it will usefull would be great.
Anyway, Thanks!
void App::RunUnityPlayer()
{
auto appArgs = ref new Platform::Array<String^>(1);
appArgs[0] = ref new Platform::String(L"-appendlog");
auto appCallbacks = ref new AppCallbacks(appArgs);
appCallbacks->SetCoreApplicationViewEvents(m_ApplicationView);
appCallbacks->SetCoreWindowEvents(m_CoreWindow);
appCallbacks->InitializeD3DWindow();
appCallbacks->Run();
}
void App::Run()
{
for (int i = 0; i < 10; i++)
{
RunUnityPlayer();
// Pump UI events for 3 secs so all of our threads waiting on UI thread get a chance to exit
LARGE_INTEGER frequency, start, current;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&start);
current = start;
do
{
Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent);
QueryPerformanceCounter(¤t);
}
while (static_cast<double>(current.QuadPart - start.QuadPart) / static_cast<double>(frequency.QuadPart) < 3.0);
CoFreeUnusedLibrariesEx(0, 0);
}
}
Hey @Tautvydas-Zilys , I have the exact same requirement but I am having a hard time understanding your solution.
I am using Unity 2018.4 with a .net back end.
I had the same problem as semih-guresci - after I do Application.Unload(), when I navigate to the MainPage all I get is a blank page.
I changed the cache mode to NavigationCacheMode = NavigationCacheMode.Disabled, that tries to re-create the page.
When you create a UWP project, it sets the appCallBack to appCallbacks = AppCallbacks.Instance. After a Unload(), AppCallbacks.Instance is null which makes it break.
So I am now trying to re-create appCallBacks like you said:
if (appCallbacks == null)
{
appCallbacks = new AppCallbacks();
}
It blows up on appCallbacks.InitializeD3DXAML(); I have the same problem as unity_0PfXqw83o46aIg, visual studio doesn’t give me any debug info other than
Exception thrown at 0x00007FFB628576D9 (UnityPlayer.dll) in UnityChessGame.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
I have mixed mode debugging on in my project settings.
You can only have one AppCallbacks object at a time. Furthermore, you need to more sure that AppCallbacks is destructured/garbage collected before creating a new one.
Can you share your full code? Is unloading a hard requirement when navigating to another page? Perhaps you can just pause Unity instead?
I made a sample project for you that shows the problem.
First page is DashPage - that has a button that loads Unity via MainPage. Unity has a Back Button, the code called is in ButtonHandlers - it calls Application.Unload(), then the code in UnityToXAMLEventCallback to navigate back to DashPage. When you go to unity again is where it breaks. I put the AppCallbacks and bridge object
in a constants class to only keep 1 instance, but it made no difference.
I can’t figure out what I am doing wrong. I updated the sample to not create AppCallbacks in App.xaml and to only create a AppCallbacks object in the main page. I am creating a new class every time with:
var m_AppCallbacks = new AppCallbacks();
Same issue, it works the first time, but when you go back and try to re-create it fails.
Correct, it crashes. I have mix mode debugging on but visual studio doesn’t give me anything helpful. Here’s the output from when I hit the go to unity button a second time after navigating back, it doesn’t show anything useful:
[0.021748 / 0.025173] - Initializing Unity runtime
onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFBD2C804B0: (caller: 00007FFBD2C801F5) ReturnHr(5) tid(2884) 80070490 Element not found.
[0.000250 / 0.025794] - AppCallbacks::SetCoreWindowEvents
[0.000005 / 0.025896] - AppCallbacks::InitializeD3DXAML
[0.055917 / 0.055917] - OnSwapChainPanelSizeChanged event Old Size (0.00, 0.00) New Size (1010.00, 508.67), m_Initialized=False.
Module information:
Built with Compiler Ver '191326128'
Built from '2018.4/staging' branch
Version is '2018.4.17f1 (b830f56f42f0)'
Debug build
Application type 'XAML'
OS 'Windows 10 (10.0.18362) 64bit'
PlayerConnection initialized from C:/projects/Unity/Research/UWP/18-examl-uwp/test-18-uwp/UWP/test-18-uwp/bin/x64/Debug/AppX/Data (debug = 0)
'test-18-uwp.exe' (Win32): Loaded 'C:\Windows\System32\wshbth.dll'. Cannot find or open the PDB file.
'test-18-uwp.exe' (Win32): Loaded 'C:\Windows\System32\FWPUCLNT.DLL'. Cannot find or open the PDB file.
Connecting directly to Ip=192.168.1.102, port=34999 ...
Socket: connect failed, error: Operation has failed with error 0x274d: No connection could be made because the target machine actively refused it.
(0)
(Filename: C:\buildslave\unity\build\Runtime/Network/Sockets.cpp Line: 415)
connect failed
(Filename: C:\buildslave\unity\build\Runtime/Network/Sockets.cpp Line: 161)
Connect failed for direct socket. Ip=192.168.1.102, port=34999
(Filename: C:\buildslave\unity\build\Runtime/Network/PlayerCommunicator/PlayerConnection.cpp Line: 475)
Connecting directly to Ip=192.168.1.102, port=34999 ...
[3.302162 / 3.358078] - OnWindowActivated event - Deactivated.
Socket: connect failed, error: Operation has failed with error 0x274d: No connection could be made because the target machine actively refused it.
(0)
(Filename: C:\buildslave\unity\build\Runtime/Network/Sockets.cpp Line: 415)
connect failed
(Filename: C:\buildslave\unity\build\Runtime/Network/Sockets.cpp Line: 161)
Connect failed for direct socket. Ip=192.168.1.102, port=34999
(Filename: C:\buildslave\unity\build\Runtime/Network/PlayerCommunicator/PlayerConnection.cpp Line: 475)
Connecting directly to Ip=192.168.1.102, port=34999 ...
Socket: connect failed, error: Operation has failed with error 0x274d: No connection could be made because the target machine actively refused it.
(0)
(Filename: C:\buildslave\unity\build\Runtime/Network/Sockets.cpp Line: 415)
connect failed
(Filename: C:\buildslave\unity\build\Runtime/Network/Sockets.cpp Line: 161)
Connect failed for direct socket. Ip=192.168.1.102, port=34999
(Filename: C:\buildslave\unity\build\Runtime/Network/PlayerCommunicator/PlayerConnection.cpp Line: 475)
Connecting to host time out, player connection will be disabled.
(Filename: C:\buildslave\unity\build\Runtime/Network/PlayerCommunicator/PlayerConnection.cpp Line: 70)
[6.528948 / 6.593972] - Initialize
[XR] Discovering subsystems at path C:/projects/Unity/Research/UWP/18-examl-uwp/test-18-uwp/UWP/test-18-uwp/bin/x64/Debug/AppX/Data/UnitySubsystems
GfxDevice: creating device client; threaded=1
'test-18-uwp.exe' (Win32): Loaded 'C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_a3efb8aa9e9e249a\NvCamera\NvCameraWhitelisting64.dll'. Cannot find or open the PDB file.
'test-18-uwp.exe' (Win32): Unloaded 'C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_a3efb8aa9e9e249a\NvCamera\NvCameraWhitelisting64.dll'
Direct3D:
Version: Direct3D 11.0 [level 11.1]
Renderer: NVIDIA GeForce GTX 1080 (ID=0x1b80)
Vendor:
VRAM: 8079 MB
Initialize engine version: 2018.4.17f1 (b830f56f42f0)
[AudioManager] InitNormal(tryDeviceDefaults = false, preferredOutputType = FMOD_OUTPUTTYPE_AUTODETECT) attempt with hardAudioDisable: false
[AudioManager] Setting output to FMOD_OUTPUTTYPE_AUTODETECT
[AudioManager] InitNormal succeeded with output "FMOD_OUTPUTTYPE_WASAPI". Driver name is "Speakerss (Realtek(R) Audio)". Speaker mode is "FMOD_SPEAKERMODE_STEREO"
The thread 0x5050 has exited with code 0 (0x0).
The thread 0x3cdc has exited with code 0 (0x0).
[3.662454 / 7.020533] - MonoManager::ctor
[0.008635 / 7.029168] - MonoManager::FillCommonScriptingClasses begin...
[0.002678 / 7.031846] - MonoManager::FillCommonScriptingClasses end...
[0.000116 / 7.064857] - AppCallbacks::SetupInputEvents
onecoreuap\drivers\mobilepc\sensors\convergence\common\pnpmanager\pnpmanager.cpp(591)\Windows.Devices.Sensors.dll!00007FFB7EEBDFD5: (caller: 00007FFB7EEAA56F) Exception(6) tid(2884) 80070490 Element not found.
Exception thrown at 0x00007FFBE509A839 in test-18-uwp.exe: Microsoft C++ exception: wil::ResultException at memory location 0x000000E4261FCF70.
Exception thrown at 0x00007FFBE509A839 in test-18-uwp.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.
The thread 0x5664 has exited with code 0 (0x0).
onecoreuap\drivers\mobilepc\sensors\convergence\api\winrt\public\internal\simpleorientation.cpp(127)\Windows.Devices.Sensors.dll!00007FFB7EEB5B76: (caller: 00007FFB7EEABB9B) Exception(7) tid(2884) 80070490 Element not found.
Exception thrown at 0x00007FFBE509A839 in test-18-uwp.exe: Microsoft C++ exception: wil::ResultException at memory location 0x000000E4261FD140.
Exception thrown at 0x00007FFBE509A839 in test-18-uwp.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.
onecoreuap\drivers\mobilepc\sensors\convergence\api\winrt\public\internal\sensorserver.cpp(68)\Windows.Devices.Sensors.dll!00007FFB7EEA744B: (caller: 00007FFB7EEA3763) ReturnHr(4) tid(2884) 80070490 Element not found.
onecoreuap\drivers\mobilepc\sensors\convergence\api\winrt\public\lib\simpleorientationsensor.cpp(160)\Windows.Devices.Sensors.dll!00007FFB7EE9182C: (caller: 00007FFB7EE8EBC3) ReturnHr(5) tid(2884) 80070490 Element not found.
onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFBD2C7E65E: (caller: 00007FFBD2C7DBF2) ReturnHr(6) tid(2884) 80070490 Element not found.
onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFBD2C7E65E: (caller: 00007FFBD2C7D7EC) ReturnHr(7) tid(2884) 80070490 Element not found.
onecoreuap\windows\wgi\winrt\display\displaycommon.cpp(411)\Windows.Graphics.dll!00007FFBD2C7E65E: (caller: 00007FFBD2C7DBF2) ReturnHr(8) tid(2884) 80070490 Element not found.
[0.115068 / 7.180047] - AppCallbacks::SetupOrientationSensorEvents
[0.127552 / 7.187736] - AppCallbacks::Load
[0.156057 / 7.187903] - Starting first scene loading
The following GlobalManagers were stripped from the build (Either because they're not used or not supported on this platform):
ClusterInputManager
Exception thrown at 0x00007FFB6285771D (UnityPlayer.dll) in test-18-uwp.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Unfortunately I can’t test that because you need Unity Pro to remove the splash screen.
I’ll create a ticket - I am trying to first see if this happens using c++ as well, but I can’t figure out the syntax to create the delegate connection to the back button.
If this is a bug, can you think of a workaround to fix? I tried setting the cache mode back to required, and putting the AppCallbacks logic in OnNavigatedTo instead, but it still crashes on draw splash screen, I don’t know what else to try. I am 90% done with my project, but it is dead in the water if I can’t find a fix for this.
The only workaround I can thing of is to not call Application.Unload when you switch to a different page, and instead call AppCallbacks.UnityPause instead. Then when coming back, reuse the same AppCallbacks object and just use AppCallbacks.UnityPause again.