Unity3D has a great core architecture – it’s easy to understand and use. However, it has some significant flaws.
One of the recurring problems I run into is that Unity requirs you to have precisely one “Scene” at any one time, but often you need to have multiple scenes at the same time. Problem? Yes, lots…
Unity 5 has some hacks to make it “sort-of possible” to have multiple scenes at once in-Editor.
Note: these were mentioned by Unity corp in August 2014, but aren’t available to most users yet
But they (appear to be) hacks: they help for a fraction of the use-cases. That’s fine: Unity has 10 years of software written on the assumption there is only one “Scene”; that’s an enormous amount of code to change! But can we do something about this?
TL;DR: I’ll put this on the Asset Store
If you just want a working solution, here’s the Unity Asset store page / support page, new versions will appear here first.
I’m using it myself on my own projects, and will do some beta testing with other people’s games. If it works well enough, it’ll go on Asset Store. I suggest reading this full post anyway – it’s an example of how to creatively solve small issues like this in Unity.
(if you’d like to beta-test this, tweet me @t_machine_org or email me (address at top of page). Unity Corp only let me have 12 beta-testers, so you’ll need to give me some info about what you’ll use it for, how soon, how much feedback you’ll give me, etc! Sorry :( )
There can be only One!
Unity has hardcoded there can only be one Scene object. It’s unbelievably hard to change such decisions (which is why it’s famously “terrible OOP design”, and we tell new programmers: NEVER do this).
So we’ll have to do everything with Virtual Scenes: things that are like Scenes, but all exist simultaneously inside the same Unity Scene.
The universe is … not … infinite
Everything in Unity is required to have a position in 3D space. There are two positions: a “world position” (labelled “position” in code) and “local-area position” (labelled “localPosition”). In the GUI, Unity displays only the local-area position, and with parenting of objects this is frequently small numbers – 0.0, or 5.0, or 1.234324, etc.
However, every object also has a global position (calculated by adding the localPosition to the parent-object’s position), and this position is affected by the maximum size you can hold in a “float” – and more: by the precision.
So, if you place objects at (0,0, 10000000000000) … you’ll hit some very odd problems. For examples of what might happen, google MineCraft’s FarLands (where you’ve travelled so far from the 3D origin of (0,0,0) that floating-point numbers stop working properly):
“As the player journeys even deeper into the Far Lands, the effects worsen to the point where the game is unplayable. At X/Z ±32,000,000, block physics stop functioning correctly. Lighting doesn’t work and the blocks, although they appear to be there, aren’t solid. If the player tries to walk on these blocks, he or she will fall into the Void. At excessive X/Z positions, world renderer no longer works, or takes incredibly long times and uses most, if not all CPU usage. It then becomes almost impossible to close Minecraft without a task manager.” – Minecraft Gamepedia wiki
Unity features we can leverage
Unity layers keep stuff apart
Unity’ layers system lets you mark things as “independent, overlapping universes”. Many missing-features and problems in Unity are officially worked-around using Layers. That’s good.
Unfortunately, someone hardcoded a tiny limit to the number of layers. As a bonus, the GUI for visualising, using, and debugging them is poor compared to most of core Unity.
So, layers work, but … a big game may not have any layers to spare. So we need to use them carefully.
Things in the same scene don’t necessarily overlap
In a game-engine, very little you see on screen is actually infinite: there’s no point. So, in theory:
- a camera can see infinitely far into the distance
- light travels infinitely far, unless blocked by objects
- physics calculations affect everything infinitely far into distance
In practice, your camera has a “far plane” (coincidentally: for almost the same reasons to do with floating-point precision as we have with position) … light usually ignore things that are “too far away” (performance optimization) … physics pre-groups things into “near enough to worry about” and “too far away to care, for now” (massive performance optimization!).
Use cases for Virtual Scenes
Here are some I’ve run into, and felt myself wanting help with:
- Using the New GUI / uGUI from Unity 5 into a game, without have stupid giant GUI 10-miles-high messing up your Editor view of the level
- Unity corp should have made uGUI have its own window for editing; they didn’t, so can we solve this?
- If a scene has multiple areas – e.g. a world-map at small scale, and individual towns / houses / dungeons at big scale – you need it all in the same scene, but physically displaced
- When you are embedding a preview-camera into your HUD (or GUI, or even in-scene), Unity’s implementation of RenderTexture etc requires you to construct a mini-scene somewhere inside the same Scene, but gives you no help or support to do this.
- We want to be able to make a bunch of these “dioramas” and switch between them
- …both while editing, and while trying-out different level-designs
- A lot of the cases involve embedding a camera-pointing-at-some-other-scene into your main Scene
- It has to work both in-Editor and in-Game
- In Unity, changing “Scene” is very very slow and wipes all data in the Editor; this breaks a huge amount of code and makes you write very long, painful, crappy code to workaround it. We want to avoid that and have multiple scenes that live in one Scene
Implementation / Solution
I’ve built a system of “Virtual Scenes”. The basic idea is that each Virtual Scene is a parent object floating somewhere very far away in the distance. Easy!
Most of the work so far went into adding custom GUI and window that lets you easily add, navigate, right-click move objects to/from virtual-scenes, etc. e.g. …
Features working at the moment:
- Each Virtual Scene has its own name (can rename whatever you like)
- Fully integrated with Unity Editor – selecting a VirtualScene in Hierarchy selects it in the Scenes Inspector, and vice-versa
- You can right-click any GameObject / selected GameObjects and “move them to a Virtual Scene”
- When moving-to-scene, if things have a parent, they got to the same localPosition in the Virtual Scene; this makes it very easy to organize things in different Virtual Scenes and move them to/from your main Scene
- A SceneManager lets you easily find, view, and jump the Editor “Scene View” to each one
- It also manages and (re-)positions them when needed (if you decide to delete some, add some, change how far “far away” is because you made your main Terrain bigger, etc)
- They optionally have a “Scene Camera” (which is a local version of MainCamera); when you jump to a scene, it takes you to “looking hrough the Scene Camera” since that’s normally what the sub-scene is being used for
- Setup is all automatic: if you open the Virtual Scene Manager, it automatically configures itself and adds a Virtual Scenes system to the current Scene — (this was hard to make work: I found some new bugs in Unity’s EditorWindow implementation. Sigh)
- Everything is serialized correctly within the Unity Scene, using Unity Serialization — (this was hard to get right, since Unity doesn’t let you debug their crappy Serializer … at all :()
Features I’d like to add:
- NOT IMPLEMENTED YET: automatic managing of Unity layers, so each Virtual Scene exists in a layer of its own. NB: the Layers in Unity suck. You’ll be limited to a small number of virtual scenes, etc.
- NOT IMPLEMENTED YET: exporting / importing Virtual Scenes (SPECIFICALLY: I’d like to be able to transfer them between Unity Scenes. Unity’s “export package” feature sucks DONKEY, and still has the same major bugs it’s had for years; I can probably do much, much better)
- NOT IMPLEMENTED YET: “SceneCam” preview system: show thumbnails of all the scenes, rather than just customised names. This is useful if you have many scenes, but more just for fun and because I think it’ll look cool :).