I delivered my first session to professionals in this
year’s PUG DevCon on 24th Aug 2013. It was fun. The response was
amazing. To clear the doubts raised by audience and to provide them with the
content I delivered during the session, posting this on my blog.
Unity3D is a popular game development engine. The
recently released version 4.2 of Unity brought a revolution. Why? Well, it
allows you to build 3D games on every mobile, tablet and desktop platform out
there for FREE! Write once, deploy everywhere using a free version of Unity. J
What I will focus here on is, Windows Store games.
Below are the prerequisites to build Windows Store Games using Unity3D –
1.
Windows 8 (as of
now)
2.
Windows 8
developer license
3.
Visual Studio 2012
(11.0.50727.1)
4.
and obviously,
Unity3D 4.2
I won’t go in to details of Unity game engine unlike my session. I will focus on windows store deployment part of our game.
So let’s start,
1.
Open Unity
2.
File->New
Project
3. Choose the directory, give a good name to your game and start developing your game
4.
Once you finish developing
your game, go to File->Build Settings
5.
Choose Windows
Store as a platform
6.
Select one out of
the 4 options available
·
D3D C++
·
D3D C#
·
XAML C++
·
XAML C#
Note
that, unity uses DirectX for rendering the game when you build it for Windows
Store. Even if you choose one of the XAML options, it still renders using
DirectX. XAML can be used as a layer on top of your game for GUI controls or
other design part
7.
When you build,
Unity creates a Visual Studio solution which you can open in Visual Studio 2012
8.
If you select one
of the D3D options while building your game you will find an App.cs in your
Visual Studio project
9.
If you select one
of the XAML options while building your game you will find App.xaml and
MainPage.xaml and their C Sharp files in your Visual Studio project
10.
Open Configuration
Manager and choose platform (x86/x64/ARM) and choose mode (Debug/Release)
11.
Run and you are
done :)
Now, let’s take a look at the 3 main things which
Mayura demonstrated in the session.
1.
Debugging – One of
the things you need to struggle for in Unity. You can’t debug your scripts
using breakpoints in monodevelop or any other editor you use for scripting. You
can add breakpoints in your unity script if you are developing for Windows
Store. Let’s see, how.
Note that, you can
only debug C Sharp scripts.
a.
Go to solution
explorer, right click on solution, select Add->Existing project
b.
Select .csproj
file created by unity while developing the game.
c.
You can see all
the project hierarchy including your assets, resources, etc in solution
explorer.
d.
Open your unity
script, add a breakpoint and run the game
e.
Breakpoint will be
hit and you are able to debug your code step by step
2.
XAML layer – You
can add the XAML controls for GUI and managing snapped/portrait views. Open
your MainPage.xaml and see the xaml code. You can see SwapChainBackgroundPanel
control. Why do we use this control and not any other? Because this xaml
control is designed to render DirectX content. Go ahead and add few Buttons,
Labels, etc. Use some nice styling and run the game. You can see your xaml
controls rendered on top layer and the game behind.
3.
Unity-XAML
communication – Just adding the controls is not enough. If you want to use it
as GUI, XAML should communicate with Unity and vice versa. When you build your
game using one of the two XAML options, you can see the following code
automatically created in your app.xaml.cs
private WinRTBridge.WinRTBridge _bridge;
private AppCallbacks appCallbacks;
public App()
{
this.InitializeComponent();
appCallbacks
= new AppCallbacks(false);
}
protected override void
OnLaunched(LaunchActivatedEventArgs args)
{
Frame
rootFrame = Window.Current.Content as Frame;
if
(rootFrame == null)
{
var
mainPage = new MainPage();
Window.Current.Content
= mainPage;
Window.Current.Activate();
_bridge
= new WinRTBridge.WinRTBridge();
appCallbacks.SetBridge(_bridge);
appCallbacks.SetSwapChainBackgroundPanel(mainPage.GetSwapChainBackgroundPanel());
appCallbacks.SetCoreWindowEvents(Window.Current.CoreWindow);
appCallbacks.InitializeD3DXAML();
}
Window.Current.Activate();
}
Let’s
see what the code above means,
private
WinRTBridge.WinRTBridge _bridge;
So
first of all, what is WinRTBridge, it's used internally by Unity, to perform
some of native-to-managed, managed-to-native operations, it's not intended to
be used by developers. Due some WinRT platform restrictions, it cannot be
created from Unity engine code, that's why WinRTBridge is being created here
and is passed to Unity engine via appCallbacks.SetBridge(_bridge) instead.
appCallbacks
= new AppCallbacks(false);
Now,
let's take a closer look at AppCallbacks class. When you create it, you specify
that your game will run on different thread, for backward compatibility reasons
you can also specify that your application can run on UI thread, but that's not
recommended, because there's a restriction from Microsoft - if your application
won't become responsive after 5 seconds you'll fail to pass WACK (Windows
Application Certification), read more here -
http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184840.aspx,
imagine if your first level is pretty big, it might take significant amount of
time to load it, because your application is running on UI thread, UI will be
unresponsive until your level is fully loaded. That's why it's recommend to
always run your game on different thread.
Note:
Code located in App.xaml.cs, MainPage.xaml.cs is always running on UI thread,
unless called from InvokeOnAppThread function.
appCallbacks.SetSwapChainBackgroundPanel(mainPage.GetSwapChainBackgroundPanel());
This
simply passes a XAML control to Unity which will be used as a render target for
DirectX 11.
appCallbacks.SetCoreWindowEvents(Window.Current.CoreWindow);
Sets
the core window for Unity, Unity subscribes to the following events (there may
be more, depending on when this information was updated) :
·
VisibilityChanged
·
Closed
·
PointerCursor
·
SizeChanged
·
Activated
·
CharacterReceived
·
PointerPressed
·
PointerReleased
·
PointerMoved
·
PointerCaptureLost
·
PointerWheelChanged
·
AcceleratorKeyActivated
appCallbacks.InitializeD3DXAML();
This
is main initialization function for Unity, it does following things:
•Parse
command line arguments, set by AppCallbacks::AddCommandLineArg
•Initialize
DirectX 11 device
•Load
first level
Finally,
you may face some problems while building the game for Windows store. E.g. you
are able to play the game in unity but as soon as you try to build it for
Windows store it gives compiler errors. That’s because you might have used some
classes or types in Unity which are not supported by Windows store yet. Things
that are not yet supported:
·
Network classes,
WWW is supported though
·
Animation on
script variables
·
AnimationEvent
callback functions with arguments (you have to provide a function with no
arguments or with AnimationEvent argument)
·
GameObject.SendMessage
(partially works, but function which accepts the message must match the message
sent, because the argument conversion doesn't work)
·
Cloth
·
Microphone
·
You can't access
C# classes from JS or Boo scripts, you should be able to access JS, Boo classes
from C#
·
JS and Boo scripts
won't pass WACK at the moment
·
Fog doesn't work
on devices with feature level < 9.3, you need to implement it manually, see this
You
can download the sample game I created during the session here. Open it in
Unity, Play around with it and build it for Windows store.
You
can download some sample Unity- Windows store games here
Let
me know in the comments or via any other media, if you have any doubts. I will be
happy to solve them. Keep visiting for more stuff about Unity, Kinect and more
And
as always, thanks for reading :)
Cheers…