Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lessons learnt from making a hit mobile game with Unity 3D

Similar presentations


Presentation on theme: "Lessons learnt from making a hit mobile game with Unity 3D"— Presentation transcript:

1 Lessons learnt from making a hit mobile game with Unity 3D
David Jefferies, Technical Director PaperSeven Ltd

2 A Bit Of History Used Unity to prototype Split/Second 2
The game + engine was large ~2mil lines code Turnaround times were slow Unity helped the developers test out gameplay ideas quickly Games programmer since 1995 Starting with Psgynosis, then Rare then joined Climax in 2003                 Was technical director of MotoGP’06, MotoGP’07 and Split/Second

3 A Bit Of History S/S engine was very large but also very efficient
                Rendering was a big part of the game. Used 84 renderer targets to make up the final image     

4 A Bit Of History At one point we even considered making S/S 2 with Unity Unity renderer was about 80% at efficient rendering models as S/S 2 Replace editor, asset pipeline and game engine with Unity Great games are made by great developers not engines. Engines are tools for the developers to express themselves

5 2010 - 2011 Unity was widely seen as a capable prototyping tool
Definitely not a commercial game engine

6 Unity I think the reality is different Model Importer
Dependency Checker Renderer Extensible Editor C# code This is what I want. I don’t want to write these modules again. You can’t google problems with your internal code!

7 Made In Chelsea Game 9 months to develop
4 coders, 4 artists plus contractors Producer/GD iOS and Facebook initially, Android update Free with IAPs #2 in the AppStore charts 19k ratings at 4.5 stars 10 hours in length if you rushed through Won ‘Best Game’ in the Broadcast Digital Awards 2014 We got the opportunity to develop the game for the Channel4 hit show                 Not the traditional demographic for game development                 This made it an exciting proposition to write something for a group of people (female 17-28) that were underserved in the game space                 Handy that Alice was closer to the target group than most game developers

8 Made In Chelsea Game

9 Made In Chelsea Game

10 How We Made It Exclusively C#
Used Prime31 plugins for most native code - IAPS, Twitter and Facebook authentication etc  Coders used a mixture of MonoDevelop and .Net MacMini server build machine that built iOS, Facebook and eventually Android Mainly developed on PC except for the iOS specific bits which were kept to a minimum We wrote exclusively in C# although some plugins were written in Javascript (mistake, difficult to debug, can’t use .Net?)                 We used Prime31 plugins for  most native code - IAPS, Twitter and Facebook authentication                  Programmers used a mixture of MonoDevelop and .Net (well I used .Net)                 We had a MacMini server build machine that spat out iOS, Facebook and eventually Android builds                 Mainly developed on PC except for the iOS specific bits which were kept to a minimum                 138MB download ended up as 231MB on disk (this is too big by the way)                 Teamcity running on a MacMini Server                 Build scripts call a static function to build based on config                 Build number written to disk and read during that step                 Archive constructed / then IPA / then uploaded to Testflight                 Signed with Enterprise profile

11 Learnings It’s easy to get something up and running
This is a great strength of Unity However, not all features scale well from prototype to full production It’s this understanding which is vital Not going to tell you what’s right or wrong There are many ways of doing things in Unity, most of them are right for some application or other This is how we do it

12 Memory Rule [1] Never write code that allocates while the game is running All allocations at load time Same rules as C++ but it’s trickier with C# Unity’s memory profiler is your friend The garbage collector will bite you

13 Memory Know the difference between class and struct
We never use foreach loops Use a heap safe Dictionary Raycast was only exception Use object pools. No runtime instantiation I’d like to stop the game if allocations happen, they’re almost always avoidable if the programmer is aware of them Heap safe dictionary is our own class that stores a list of the keys alongside the dictionary which means you can iterate through the keys without having to iterate through the dictionary. This avoids the ienumerator allocation. Physics.Raycast sometimes allocates memory. No way round this unfortunately

14 Exceptions Rule [2] Always use Fast but no Exceptions in production code Speeds up managed to native calls by 3X Managed code exceptions are still thrown Write the exception to a log file and crash Send the log file to your metrics server Even transform.position is a native call so 3X speedup on native calls is a big win

15 Exceptions void HandleLog(string logString, string stackTrace, LogType type) { string log = DateTime.UtcNow.ToString("HH:mm:ss") + " " + type.ToString() + " :\t" + logString; if (!string.IsNullOrEmpty(stackTrace)) log = log + "\n\tstackTrace :\n" + stackTrace; } using (StreamWriter file = new StreamWriter(Application.persistentDataPath + "/logs" + "/LogFile_" + logSessionID + ".log", true)) file.WriteLine(log); if (type == LogType.Exception) PlayerPrefs.SetInt(APP_CRASHED_KEY, 1);

16 Scenes & Prefabs Prefabs are a great way of encapsulating code and data When placed directly in a scene they make it un-mergeable If a prefab is edited in a scene and not applied it becomes unique to that scene References were forever being lost Rule [4] No references between different prefabs

17

18 Scenes & Prefabs Rule [5] Have a scene structure that determines which prefabs to load & initialise Load all the prefabs in the level folder Custom intialisation steps to manage initialisation dependencies Inject dependencies into the components Start game

19 Scenes & Prefabs

20 Custom Setup Steps Awake Load AssetBundles Load Prefabs
HandleInitFirstTime SetupDependencies HandleInit Update

21 Code Structure No Singletons
Loaded prefabs are available as a dictionary to all classes Dependency injectors push dependencies into the components Injectors are destroyed after being run

22 Code Structure public class GameTimeInjector : GameResourcesInjector<GameObject> { [SerializeField] private string _pauseControllerObject = "PauseEventController"; public override void Inject () GameTime _gameTime = GetComponent<GameTime>(); PauseEventController pauseController = GameResources.GetLoadedObject(_pauseControllerObject).GetComponent<PauseEventController>(); pauseController.AddPauseableObjects(_gameTime); }

23 Code Structure Common Library shared between all games
Lives in the Plugins Folder Enforces the rule that game code cannot exist in the library We use a repository within a repository Warnings as Errors using gmcs.rsp & smcs.rsp

24 Code Structure Listener pattern Reduces dependencies between modules
Uses the dictionary of objects to connect listeners and distributors

25 Code Structure public class DriveAutoSaverInjector : GameResourcesInjector<GameObject> { [SerializeField] private string _saveStateDataObject = "StateManager"; [SerializeField] private string _gameStateObject = "Game"; public override void Inject() AutoSaver autoSaver = gameObject.GetComponent<AutoSaver>(); GameState gamestate = GameResources.GetLoadedObject(_gameStateObject).GetComponent<GameState>(); gamestate.PostEndOfRaceListeners.Add (autoSaver); }

26

27 Over Air Update Rule [6] All prefabs are built as asset bundles
This allows us to update all of the game data over the air Versions.xml exists on Amazon AWS and serves new prefabs to the game Next time the game runs it loads the new downloaded prefabs rather than the bundles prefabs Use [SerializeField] attribute for private variables

28 Out Of Memory Write guard file when app launches
Delete it when app enters the background If you launch and the file is there then ran out of memory Tell user to reset their device Log with metrics server Use assembly stripping

29 Source Control Internal Git repository hosted on our network
Everyone in the studio uses the Git client Problems with empty directories / meta files

30 Auto Build Hook into Unity’s build process
Have a config file that defines all the build settings We use TeamCity Building iOS more difficult than it should be Upload to TestFlight / HockeyApp Signed with Enterprise profile

31 Auto Build We use Mind Candy’s Teamcity Unity3D runner
iOS Build is fiddly Write build number Build Project Build Xcode Archive Build IPA Upload to TestFlight Lots of messing around with Provisioning Profiles

32 Performance Scaled some features depending on device
Fast but no Exceptions No memory allocations Do all possible calculations at build time i.e. less characters on iPhone4

33 That’s It Any Questions


Download ppt "Lessons learnt from making a hit mobile game with Unity 3D"

Similar presentations


Ads by Google