Need a slider in your game or app and want text on the handle?
The setup for this is pretty simple, you’ll need a slider, a label and a script..
The Slider
Create a slider.. then select a minimum and maximum value. For the slider above, I’ve also checked “whole numbers”.
The Label
Once you’ve created the slider, find the Handle child.
Create a new Text (or ideally a TextMeshPro – Text) object under the Handle.
Center the text object, and set the color to something that works well with your handle.
And finally, add this script to the text (or textmeshpro text) object..
Code
Note: If you don’t use TextMeshPro (which you should), you’ll need to change the references to just be “Text” & remove the top using statement.
Formatting
The default format for the script above shows a degrees symbol. You can modify that by editing the FormatText field. The code uses string.Format, and the {0} is replace by the actual value.
Last weekend, I had the privledge of attending the LA HoloHack. The HoloHack events are put on by Microsoft to expose more developers to the HoloLens, see what they build, and expand the platform. I love hackathons, so as soon as I heard about it, I signed up, and with a team of experienced developers, we pre-planned out project and arrived excited to build something great.
Prior to this event, I’d used the HoloLens a handful of times. I’d gone through the best demos, attended a couple HoloLens meetups, and spent some time with the emulator, but this was going to be the first full HoloLens project we’d all get to build.
What I didn’t Like
Setup
The setup process for developing on HoloLens seems like it’d be pretty straight forward. Install Unity, and the tools on the HoloLens page.. then good to go, right?
Unfortunately, with my laptop, I had previously installed VS 2015, but did not check the UWP boxes during install. Because of that, I couldn’t get anything to work.. the emulator wouldn’t install, I couldn’t do a hololens build..
And the only way to fix it was to re-run the VS2015 installer (and check the UWP boxes)..
It’s supposed to work with 2017, but it didn’t work for me, and the developers on my team who tried using it had constant VS crashes.
Field of View
Everyone I’ve ever talked to about the HoloLens complained about FOV.. For good reason, it’s really small, and can be really limiting. It’s not so much the horizontal FOV either.. while that’s small, it’s managable. The vertical FOV is only about 16deg..
Now while it’s frustrating and limiting, it doesn’t mean the device is DOA, just that you need to really heavily consider the constraints when designing.
In our case, the original game idea we had included a lot of looking up and down, which doesn’t work well at all with that vertical FOV. This was a big hit for us, but a good learning experience for myself. It was a reminder to always understand the limitations of the hardware and really consider them when designing. While a game that requires lots of up and down scanning won’t work well, there are quite a few things the hololens excels at which we should have taken advantage of.
What I liked
Environmental Scanning
This was amazing.. scanning the environment is not only fast, but extremely easy to setup. By adding a single component, you can generate a mesh for the environment that’s auto updated as more is scanned in.
Placing something on the wall just requires a quick raycast against the environment layer to get the point and normal.
Want a wireframe scan visualization of the world? No problem, just drop on another component and it’s there automagically 🙂
The same went for finding wall and floor planes, it’s all thought of and easily accessible.
Seeing through walls
This was probably the coolest part of what we did. If you’ve never tried a hololens, it’s hard to explain.. but if you create your app right, you can make it appear as if you’re seeing into or through a portal. In our case, we made it look like you could break out the wall and see inside (though the inside of our wall was made of cheese). This effect works in 3D, so you can look inside the wall from any angle and see what you’d expect.. it’s mindblowing and probably the coolest effect I’ve seen on the HoloLens.
HoloLens Toolkit
Before the event, I didn’t realize there was an entire toolkit built up for the HoloLens. I should have known Microsoft would do it.. and I’m glad they did. The toolkit provides way more than I can describe here, so if you’re interested, check it out on their github page – https://github.com/Microsoft/HoloToolkit-Unity
Voice Commands
Setting up voice control for the HoloLens was amazingly simple. With a couple lines of boilerplate code, and a single event registration, you can bind any command to a method call. This is actually a feature of UWP apps on windows 10+, but I’ve never had use for it before HoloLens. If you need voice control, it’s definitely worth trying out Microsofts solution.
Coding for the device
Since the HoloLens is so well integrated with Unity, development was extremely easy to get started with. Other than the specific location of your MainCamera (0, 0, 0), and the requirement for a solid black clear flag, everything else was pretty much typical Unity development. Only input handling was a little different, but it wasn’t difficult. Overall, developing for the device was a great experience.
Multi-player
Surprisingly, many of the entries supported multiple players sharing a world. And from the looks of it, setting this up is actually much less difficult than you’d expect. You can learn more about it in the HoloGrams 240 course here: https://developer.microsoft.com/en-us/windows/mixed-reality/holograms_240
Recommendations
If you’re going to jump into HoloLens development, look for opportunities where the HoloLens has a distinct advantage.
Things to watch out for
If your game will work fine in VR, it’s probably not a good fit for AR..
If your game requires the player to look all around and keep track of multiple things, it probably isn’t a good fit..
Games where the player needs to be very close won’t work well… the ‘ideal’ near clip plane is around 1.5m..
Things that are great
Overlaying onto real world people.. even putting bars over their heads with extra info can be a good starting point.
Using the environment.. placing things on walls, having things run around, float in the world..
Interacting with the environment.. have things bounce on the floor, pop and explode, etc.
Audio / voice control.. it works great and it’s easy to implement (just don’t use common phrases other people in the area will randomly say)
Conclusions
While our project idea totally failed, and we didn’t come close to winning.. I learned a ton at this hackathon. If you happen to have a HoloHack pop up near you, I definitely recommend going (Microsoft hosted events are always great)..
I’m excited for the next one, and have a few ideas that I think will work much better now that I have a stronger grasp on the devices strengths.
If you have some HoloLens ideas and want feedback, feel free to reach out, I’d love to talk about it more 🙂
If you’ve lost scene changes due to a unity crash, never let it happen again! Scene recovery in Unity3D is actually pretty easy in most cases, but it does require you to pause and think before you just re-open the project.
Follow these steps and you can save yourself from recreating hours of work from a forgotten save.
Check out this example
I’ve just saved my scene, it’s pretty simple as the Hierarchy shows.
I’ve been working a while, built an amazing scene, but somehow I forgot to save…
I hit Play…
And Crash!
Now because I forgot to save, I have two options:
Restart Unity
Find the backup file and recover my work
DON’T RESTART UNITY!
Browse to the Temp folder of the project (my project folder is C:\Git\UnityTips\)
In there, you’ll see a folder named “__Backupscenes”
Here you’ll see a 0.backup file. This is actually the most recent version of your scene (saved right when you hit play).
Copy the 0.backup file into your assets folder and change the extension from .backup to .unity.
Then just double-click that 0.unity file and Unity will start with your recovered scene.
If you build a VR game or experience, there’s a good chance you’ll end up needing some menus. There are a lot of great ways to build VR menus, ranging from basic laser pointers to some amazing interaction based systems. Since laser pointers are one of the simplest and most common systems, this guide will focus on how to create them. We’ll discuss how to use the SteamVR Laser Pointer system ( SteamVR_Laserpointer.cs ). And we’ll make your standard Unity UGUI (4.6 UI) interface work with the laser pointers.
SteamVR Laser Pointer (steamvr_laserpointer.cs)
The SteamVR Laserpointer is included in the SteamVR asset pack. Once you’ve imported the asset pack, you can see the script located in the SteamVR/Extras folder.
CameraRig & Setup
For this example, we’ll use the included [CameraRig] prefab and make a few minor modifications.
Create a new scene.
Delete the “MainCamera” from the scene.
Add the [CameraRig] prefab to the scene.
The CameraRig prefab is located in the SteamVR/Prefabs folder.
Select both theController (left) and Controller (right) children of the [CameraRig]
Remove the SteamVR TrackedObject component.
Add the SteamVR_TrackedController component
Add the SteamVR_LaserPointer component
Select a color for your pointers. I’ve chosen RED for mine…
VRUIInput.cs
Because the laserpointer script doesn’t handle input itself, we’ll need to add a new script to tell our UI when we want to interact with it.
Create a new c# script.
Name it VRUIInput
Replace the contents with this.
Attach the VRUIInput component to both the Controller (left) and Controller (right).
UpdatePoses
Update: this is fixed and not needed as of SteamVR 1.2.2, this fix is no-longer needed. Upgrade to 1.2.2 and skip this section! 🙂
Before your controllers will track, you’ll need to add the SteamVR_Update poses script to the camera. This is a known bug in the latest SteamVR asset pack.
Select the Camera (eye) child of the [CameraRig]
Add the SteamVR_UpdatePoses component to it.
Half way there!
If you press play now, you’ll see laser pointers beaming out of your controllers. They won’t do much yet, but go ahead and check them out to make sure they’re visible.
The UI
It’s time to create a UI that we can interact with.
Canvas
Create a new Canvas.
Set the RenderMode to “World Space”
Set the transform values to match these.
Scale x = 0.01
Scale y = 0.01
Scale z = 0.01
Width = 500
Height = 500
Position x = 0.0
Position y = 0.0
Position z = 8.0
Panel & Button
Under the Canvas, create a Panel.
Under the Panel, create a Button.
VRUIItem.cs
For our button to interact with the laser pointer, we need it to have a collider.
That colliders size & shape need to match our button. We could do this manually, but to avoid having to resize the collider whenever the button changes, you can use this simple script.
Create a new c#Script.
Name it “VRUIItem”
Replace the contents with this.
Attach the VRUIItem component to the button.
You should see a BoxCollider added automatically and scaled to the proper size.
Select the Button Component.
Change the Highlight color to something more obvious.. like green..
Add an event handler that changes the Text component to say something different (so we can tell if the click worked).
Conclusions
Here, I’ve duplicated the button 12 times and resized it a bit to show a bit more action. Go ahead and try that yourself, or build a real menu for your game now. 🙂
The SteamVR Laser Pointer component, combined with a couple simple scripts, can get you up and running in minutes. From here, you can simply replace the OnClick events with any normal Unity UI click events you’d use in a non-vr game.
While I’m a big fan of unique and interesting menu systems for VR, laser pointers are definitely an easy to use and intuitive method for input. And for some games or apps, they’re definitely the preferred choice.
VRTK
It’s worth noting that another great way to setup UI interactions is via VRTK (VR Tool Kit). VRTK is something I’ve used in the past and love. It’s pretty easy to get started with and adds a ton of functionality beyond just laser pointers. You can read more about VRTK here.
A few weeks ago, the new Unity Remote Settings Beta was announced. The system is designed to allow developers to modify game settings without pushing an update. This can be used for anything from toggling a live event, unlocking new content, tuning game balance, switching on new features, or any other change that doesn’t need new code or assets. Prior to the Remote Settings system, you’d need to setup your own service somewhere and write your own code to call into it (or find a good 3rd party solution). Now, it’s being built in and pretty easy to use.
Getting Started with Unity Remote Settings
The Unity Remote settings asset is available on the asset store.
Import the package to a new project.
Open the Services Tab
Enable Unity Analytics
If you don’t have a project ID setup, you’ll need to do that now with the Create option.
The Dashboard
In the Analytics area, click the “Go to Dashboard” button.
This should open your web browser to the Unity Analytics dashboard.
Creating a Setting
To create a new setting, you just need to choose a name, a type, and a value.
Create one named “cubesToSpawn”
Set it to an Integer (int).
Set the value to “4“.
Click add.
Syncing Settings
After you add or change a setting, you’ll need to Sync it.
Click the Sync button.
Back to Unity
Now that we’ve created a setting and synced it, we’ll need to pull it into our project.
Remote Settings GameObject
For the settings to work, we need a GameObject with the RemoteSettings script attached to it.
Create an empty GameObject.
Name it “[RemoteSettings]“.
Add the RemoteSettings component to it.
Something to Sync
It’s time to start pulling in our variable. There are two ways you can do this.. either by assigning a parameter in the Remote Settings inspector or by code.
Personally, I prefer the code method, so I’ll show that here.
Create a new Script.
Name it “CubeSpawner”
Replace the contents with this.
Create a new GameObject.
Name it CubeSpawner.
Add the CubeSpawner component to it.
Press Play and watch your cubes spawn.
Changing the Value
These settings wouldn’t be useful if you couldn’t modify them.
Go back to the Dashboard and change the cubesToSpawn value to something else.
Click Sync – VERY IMPORTANT, THEY WON’T UPDATE IF YOU DON’T DO THIS.
Stop and re-start your game in the editor then watch the number of cubes change.
Conclusions
The new Remote Settings system seems pretty useful. I’ve done similar things where I needed to setup my own services for this kind of functionality.. and plenty of others have done the same.
Now, we have a pretty simple and standardized method for changing variables in our games or apps without doing an update.
Next time you need to have some adjustable settings, try out the Remote Settings asset.
Note: Also, when you want to go live, make sure to put your settings under the “Release” option. We used “Development” here.. but that won’t work in a release build.
AssetBundles are a great feature built into Unity3D. They can allow you to update your game with no user interaction or even stream assets after the first install so your package size isn’t too big for mobile. With proper use of assetbundles, you can easily replace textures, gameobjects, and scenes on the fly.
There are a couple ways you can manage your asset bundles, from very basic manual generation to ultra complex systems built for big games with a lot of updates. Today, we’ll cover the new ‘experimental’ asset bundle system. We’ll generate some bundles, and use the bundles to update a game.
Download (or clone) the project and copy the “Editor” folder into your existing project.
Wait a few seconds for the editor to re-compile, then open the “AssetBundle Browser” window.
You should see a window like this, with no bundles created yet.
In your scene, create a cube and a sphere. These will represent our player and his enemy.
Give them each a material of their own and color them accordingly.
Here’s what mine looks like.
Create a “Scenes” folder.
Save the scene in the “Scenes” folder and name it “Level1”
Select the Level1 scene in the project view, then look to the bottom of the inspector.
You’ll see an AssetBundle area.
Click on the dropdown and select “New…”
Name the new bundle “level1”
The bundle names must be lowercase. If you put an uppercase name there, it will automatically correct itself.
Save your scene.
Now go back to the AssetBundle Browser window.
You should see your newly created AssetBundle there like this.
The right side is showing the assets included in the bundle. Notice that the Player & BadGuy material are in the bundle as well. This is because they’re used in the “Level1” scene and the system is automatically including our dependencies.
Building the Bundle(s)
Click on the Build tab
Select an output folder for the bundles. This is where bundles will be saved so you can upload them to a web server later.
Check the box for “Copy to StreamingAssets“. Doing this allows us to use the bundle without hitting the web server, and includes it in the build. Once we have the bundle on a web server, we can delete this.
Click Build
The Output
Your asset bundles should be built and if you browse to the folder you selected for the output path, it should have contents similar to this.
Back in the editor, you should also see a “StreamingAssets” folder that contains the same files like this.
Loading Script
Create a new folder named “Code”
Create a script in that folder and name it “Loader”
Replace the contents with this script.
Loading Scene
Now that you’ve created a bundle, it’s time to use the bundle.
Create a new scene.
Name it “Loader“.
Create a new gameobject and name it “SceneLoader”
Add the Loader script to the “SceneLoader” gameobject.
Save the scene
Testing
Press play and you’ll see your “Level1” scene is loaded.
How does this help?
You may be wondering how this is useful, what have you done that’s special? Right now, we’re just loading a scene that’s exactly what we have in the scene file..
Let’s change that and see if it makes more sense.
Open the “Level1” scene in the editor.
Change the “player” to be green.
Add another bad guy..
Save the scene.
Press play and check out your green player and 2 bad guys…
Stop playing and open the “Loader” scene.
Press play again, and you’ll see that the version of Level1 loaded is what you exported previously, not the current state of the scene.
Real world Scenarios
In a real project, your asset bundle would be the more ‘updated’ version of the level. It could even be a completely new level. You could have swapped out all the art, changed the style, or just fixed a minor bug with the placement of an enemy.
Here, for simplicity of demonstration, we did it a little backward, but hopefully you can see where this can go.
Loading from the web
So you may be wondering how to stream these asset bundles from a web server.
Streaming your assets can be extremely valuable. It allows you to bypass the ‘over the air’ limits for downloading mobile games while not on wi-fi. It also allows you to do your own game updates without requiring any user intervention (no need for players to go download the next version of your game, it’s automatic when they start).
Open the “Loader.cs” script
Replace the contents with this.
Open the Loader” scene.
Press Play.
Now watch as your level is streamed in from a remote web server.
If you look at line 12 of the Loader script, you can see the URL where I’ve placed the bundle.
This call is requesting the bundle (with the required request.Send() right after it).
Then in Update, we check to see if the request is done. If so, we load the asset bundle with the GetContent() method, and load our scene.
Hosting your Bundles
You can host your asset bundles on any web server that gives you direct access to the files. I use Azures Blob container storage for mine, but you can host on AWS, cloudflare, or anywhere else you know how to setup (most of them are pretty easy to get going with).
Simply take the output that you had from the bundle build step, and copy those files into your web server.
Then make sure they’re publiclyaccessible. How you do that will vary by platform, for Azure it’s a simple menu item in the Storage Explorer.
Conclusions
In this post, I’ve covered the bare minimum basics of creating and loading an asset bundle to do an update. In most real world scenarios, your game and bundles will be quite a bit more complicated, but the concepts still carry through.
There are a few things you’ll want to do differently when it comes to real sized assets on a device, like loading everything async (including scenes). As you get deeper into AssetBundles, you’ll likely build up a mini-ecosystem of your own that handles things cleanly (but again that’s too much to cover in a single post).
It’s also more common to just load art assets and gameobjects instead of scenes. In-fact I’d bet most people never need or want to load a scene from a bundle, but instead just want to update their assets, or load data that configures the scene (can be much less bandwidth, but more work of course).
This is meant as a starting point and hopefully conveys the concepts so you can dig in deeper.
Followups
If you’re interested in learning more about asset bundle loading, I highly recommend the following sources.
Unite Q&A on asset bundles (talks quite a bit about the Bundle Viewer asset you used above)
If you’ve ever wanted to add real world maps to your Unity game or application, you’re in luck. This week, I tried out the Mapbox Unity plugin and have to report that it’s extremely easy to use and pretty powerful. If you want to get real world maps like PokemonGO, or even generate a voxel world from real terrain, mapbox makes it quick and painless to accomplish. These Unity3D maps can be generated dynamically at runtime or if you have a specific location you can pre-build them and include them with your app or game.
Getting the Unity3d maps SDK (MapBox)
You can download the mapbox Unity SDK here: https://www.mapbox.com/unity/
It comes as an .assetpackage file that you import into your project.
Account Setup
Before you can use mapbox in your application, you need an account and an API key. Create an account on the mapbox site.
If it’s valid, you should see the “TokenValid” notification in the window.
Examples
The first thing I’d recommend you try is load up the various example scenes that come with the package.
These examples show a good sampling of the things you can do with the mapbox plugin.
Start with the Slippy demo, it’s likely the most applicable for your projects.
It shows how to select an area and start scrolling along, loading in new tiles as they’re needed (much like you’d do if you were tracking a persons real world position).
The mesh here is 3d, you can also run on it, fly over it, or anything else you’d do with a 3d terrain
You can adjust the starting location and zoom range with the MapController gameobject in the scene.
What kind of maps can I have?
If you take another look at the MapController, you’ll see there’s a Map Visualization field.
The Map visualization controls exactly what it says, the visuals of your map. You can customize it or build your own from scratch (I’d recommend customizing a few first).
They’ve also bundled a variety of visualizations into the plugin, if you search and replace (or try out other demo scenes), you can see how some of these look.
For example, here I’ve swapped in the PoiDemoVisualization and moved our starting point to London
Voxel Maps
Or.. maybe you want a minecraft style voxel representation of your area..
The VoxelWorld scene shows exactly how to set this up.
Pre-building a map
One thing I needed to do and you may as well is pre-generate a map for a specific area.
If your application or game only needs a certain geographic area, maybe a map of some specific city, or a big landmark like the pyramids.. you can build it and bundle it in with very little work.
The MapController class that ships with the plugin is meant to be a demo/starting point, but with a little extension you can change it to be an editor time generator instead of runtime.
The quick and dirty way to do this is just edit the MapController class and move the map generation / initialization to a context menu.
Change this..
To this..
And you’ll have a context menu like this that you can use before pressing play.
It’s important to note that if you do this, you WILLbreak the demos. So if you’re even a little comfortable with c#, you’re probably better off copying the MapController class and making your own modified version of it. Or if you’re very comfortable with c#, dig in and build something awesome.
Range
The last thing I want to cover is the Range field. This tells Mapbox how many tiles away from the Lat/Lng you want to generate in each direction (N, E, S, W). It defaults to 0, but you can adjust it to the values that feel right for your specific application.
Performance Notes
While I was trying out this plugin, I wanted to know how it would fare for performance. With some of the demos I quickly realized there was a big variance on the vertex count depending on some options.
The biggest performance hit I came across was with generating roads. With roads on, in a smaller metropolitan area, my vertex count went from around 500,000 to 20,000,000.
This could be a bug, or it could be me using the SDK wrong, I’m not sure (though I’m going to ask the developers). But if you need to keep your counts down, I’d recommend disabling road generation in your visualiaztion settings (or using one of the predefined ones that doesn’t generate road meshes).
Pricing
I haven’t had a need to pay for Mapbox yet because my usage is pretty small. The free plan covers up to 50,000 users a month on mobile, and after that the price jumps up quick to $499/mo.
But if you have more than 50k users a month in your app or game and collect any revenue at all, the cost should be nominal.
The big limit on the free version seems more than generous and is probably the tier most people are in.
if you pre-generate the maps, you’re never calling the sdk and wouldn’t hit this either, but again that’s only valid for uses where you don’t need the whole world, just a tiny area.
Conclusions
I really love this Mapbox SDK and the fact that it’s free to use for most projects. It’s easy to get setup with and customize to your hearts desire. I plan to keep using it going forward and dig in deeper to discover all the power inside.
Design patterns are reusable solutions to common problems found in software projects. Using good design patterns in Unity can help keep your project clean, maintainable, and easy to extend. It also makes them easier to build.. Today, I’ll cover the State pattern and the basics of building a State Machine in Unity3D.
The state pattern is a behavioral software design pattern that implements a state machine in an object-oriented way. … This pattern is used in computer programming to encapsulate varying behavior for the same object based on its internal state.
An implementation I don’t like..
There are a few ways you can implement a state pattern in Unity. One of the common methods I see is done by using the switch statement. It generally looks something like this.
Problems
While this technically works, there are some serious issues that will arise over time.
First, all of our logic is now inside this single class. Attacking, defending, returning home, and any other state we want to create all need to be added here. This will lead to a big bloated master class for our AI. It will also make our code more likely to break since we’re editing the same class for every type of logic. Before long, this class could easily turn into a 1000+ line disaster.
There also isn’t a great way to deal with events that happen on a state enter and exit. Quite often, we want a character or object to do something when it enters a state, repeat an action while it’s in that state, and do something totally different when it leaves the state.
With this setup, we’d have to add more switches for entering and exiting state, further bloating the class and making everything harder to understand.
A better Implementation
A better approach is to have each state be it’s own class, generally with a base ‘state’ class that they inherit from.
This way, the character or object only needs to have a reference to it’s current state and a call to make that state update. When we want to add a new state, we just create a new class.
Using this method, our character class looks a bit different:
You may notice that the classes are about the same size.. but that’s only because the first version doesn’t actually do anything (mainly to keep it digestible). If that first class were doing everything the system I’m going to show you did, it’d be huge.
How does it work?
If you look at the Update method, you’ll see that it simply calls the Tick() method on the current state. With that call, the state controls what the character will do each frame.
We also have a SetState method that allows us to pass in a state we want the character to enter. By calling SetState and passing in different states, we can completely change the behavior of this character, without changing anything in the character class itself.
Depending on your setup, it may be advisable to keep states around and switch between them to avoid garbage collection. To keep this easy to understand, I’ve skipped that, but it’s worth keeping in mind if your state changes are fast and you’re on a platform where it matters.
What’s the State class?
The state class is an abstract base class we’ll use for all states we create. It defines a very basic contract for what a state must implement and other things it can optionally implement.
The character reference is also added to this state base class, because all of our states in this example will interface with a character in some way. We take the character in the constructor of our state class and keep it in a protected variable so it’s available to our state classes.
We also have the abstract Tick() method. Making it abstract means that our state classes are forced to implement it.
In contrast, we have two virtual methods for OnStateEnter() & OnStateExit() that are optional. Because they’re virtual, they have a default implementation that does nothing, and aren’t required to be implemented.
That’s the entirety of the state class.. pretty simple right?
Creating a State – Return Home
Now that we have the basics, let’s create an implementation of a state that we can hook up to our character.
The return home state simply makes the character return to it’s home location. Since we’re not actually defining the destination for home, it’s the default Vector3.zero.
Tick
The Tick method tells the character to MoveToward the destination (0, 0, 0).
The MoveToward method is on a version of the character at the end of this post. In a real project, this movement would probably be controlled by another component like a ‘CharacterMovement’ class or something else.
Then it checks if the character made it home, and if so it tells the character to switch to a ‘wander’ state. Notice that we pass in the character when creating the new state. This is because our state is designed to require a character.
EnterState
We also change the color of the character when the return home state is entered via OnStateEnter. So as a character is going home, it’s blue.
Creating another State – Wander
For a state machine to make sense, we need more than one state. In-fact, our return home state actually wants to switch the character to a wander state once it’s done, so we need to create that wander state.
The wander state will pick a randomlocation and move the character toward that position. When it reaches that position, it’ll pick another spot to wander to.
It will continue to do this until it’s wandered for 5 seconds (based on our wanderTime variable). At that point, it will tell the character to go back to a ReturnHome state (line 43).
The wander state also changes the color of our character to greenvia the OnStateEnter method.
Let’s see what it looks like
Here, I’ve created a scene with a dozen of the ‘characters’ represented as cubes.
You’ll see them wandering around while they’re green, then going to home again when they’re blue, and repeating the process.
The Full Character
I mentioned above that the full character class is here with the MoveToward method. Again, in a real project, I’d recommend keeping your basic movement seperated into another component, but to keep this simple, here it is in the Character class.
Conclusions
The state pattern is amazingly powerful. You can build AI systems, menus, and more with ease once you get comfortable with this pattern.
This state machine is also very basic and can be extended to do things like caching states (to avoid new memory allocations) or customized more to your needs.
Another great way to build state machines is via scriptableobjects. A state machine setup using scriptableobjects can be easily configured in the editor/inspector by designers without ever touching code, but that’s a bit more complicated subject that I may dive into later.
Next time you need to build a little game logic, try setting up a state machine of your own (or copy this one as a starting point), I’m sure it’ll help and you’ll enjoy the new pattern.
Not long ago, I released a small post on object pooling with a basic sample. That example was of a unity pooling system that was very un-opinionated, only requiring an interface. Today, I’m sharing another pooling system that’s similar but works a bit different. This system requires even less code to interact with, but does have one unique requirement.
This pooling system also has a few more options for usage available via overloads in the Get call that you’ll see soon.
Why Pool?
Pooling gameobjects is essential for good performance. Instantiating a gameobject is slow and can impact performance significantly, especially if you do a bunch of it (like with bullets in a shooter). Pooling resolves this problem by re-using objects that are already instantiated and ready to go. And it’s easy to do!
Usage
Before I go into the details of how the pooling system works, I want to show some examples of how it’s used.
To get an object from this pooling system, all you need is a reference to the prefab and a single call to Get().
This pooling system actually has a variety of ways to get the pooled object to make it a bit more flexible.
The test class below shows a few of the different ways you can get an object along with a log entry of what it’s doing differently.
The Pooling System
To make this work, we need 2 common classes. We need the Pool class and the PooledMonoBehaviour class.
The Pool class handles organization of the pooled objects.
It is responsible for the following:
Tracking which objects are available to be used
Providing an object when one is requested (using Get())
Instantiating and adding objects to the pool when needed
Returning objects to the pool when they’re disabled.
Pool.cs
The PooledMonobehaviour base class
The PooledMonobehaiour is a base class that any pooledobjects need to inherit from. This is the one ‘requirement’ I mentioned at the beginning.
This class’s primary responsibility is calling the OnDestroyEvent when it’s disabled. That event tells our pooling system to re-add the object to the pool and is critical for the system to work.
But we also get some other benefits by using this base class.
First, we can define the default pool size on the prefab itself. There’s no special place to define the pool sizes, you just set it on each prefab individually as needed.
Additionally, the Get methods on the class allow us to get an instance with nothing other than a prefab reference.
PooledMonobehaviour.cs
Making a class poolable
To make a class poolable, inherit from PooledMonobehaviour like this.
Projectile.cs
Note: If you need to use OnDisable in your pooled object, be sure to override the base OnDisable method and call it with base.OnEnable()
What about Pre-warming?
If you’d like to pre-warm your object pools (which is often a good idea), this PoolPreparer will do the job.
To use it just drop the component on an empty gameobject and assign all the prefabs you want pre-warmed, it’ll do the rest.
PoolPreparer.cs
Conclusions
There are countless different ways you can build a pooling system. Of the ways I’ve done it before though, this is one of my favorites. Primarily because usage only requires a prefab reference… This system as presented here is not setup for multi-scene scenarios though, so if you need your pools to persist across scenes, make sure to add that functionality.
Whatever you decide though, be sure to use some sort of pooling system when it makes sense. If you’re building a mobile game, it almost always makes sense… Or if you’re spawning 100’s of objects all the time, pooling them will help with performance..
And if you have a prefered pooling system of your own, be sure to share it in the comments! 🙂