All posts in "Unity3D"

HoloLens Unity Development Impressions

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 🙂

 

Continue reading >
Share

Removing Empty Unity Folders & Meta Files

By Jason Weimann / June 28, 2017

Ever delete directories in Unity only to find out the .meta files and directories still exist?

Do you look in source control and see dozens of meta files for folders you thought were gone?

This happened to me more than once, so I built a quick tool to delete ’empty’ folders that were still lingering due to a .meta file.

Left with this situation, I had two options:

  1. Of course I could just look at the list of files and folders.. go in and delete them..
  2. I could write an editor script to do it for me..

Option #2 seemed more fun (even if not worth the time).. so here it is:

Code

Continue reading >
Share

Unity3D Crash Scene Recovery Trick

By Jason Weimann / June 20, 2017

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:

  1. Restart Unity
  2. 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.

Special Thanks to @AdamTuliper for teaching me this one at the OC Unity Meetup!

Continue reading >
Share

SteamVR Laser Pointer Menus – Updated for SteamVR 1.2.2

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 the Controller (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.

 

Continue reading >
Share

Unity Remote Settings

By Jason Weimann / June 14, 2017

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.

Continue reading >
Share

How to use AssetBundles to update your Unity3D games

By Jason Weimann / June 4, 2017

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.

Project Setup

Create an empty project…  that’s it.

AssetBundles Browser

While the new asset bundle system is in development, it can be downloaded from the GitHub site here: https://github.com/Unity-Technologies/AssetBundles-Browser

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 Browserwindow.

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 “Scenesfolder.

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 selectNew…

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 “Level1scene 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 Loaderscene.

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 publicly accessible.  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)

 

Asset Bundle Experiemental Forum

https://forum.unity3d.com/forums/asset-bundles.118/

Asset Bundle Fundamentals – Great info on bundles and how they work, including dependencies, loading and more.

https://unity3d.com/learn/tutorials/topics/best-practices/assetbundle-fundamentals

Continue reading >
Share

How to add real world Unity3D maps to your game or application with Mapbox

By Jason Weimann / May 29, 2017

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.

Visit your API Tokens page and copy your api token: https://www.mapbox.com/studio/account/tokens/

Open the Mapbox window.

Enter your Access Token

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 WILL break 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.

 

Continue reading >
Share

Unity3D Design Patterns – State – Building a Unity3D State Machine

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 random location 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 green via 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.

Continue reading >
Share

Unity3D Object Pooling – Advanced

By Jason Weimann / May 25, 2017

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:

  1. Tracking which objects are available to be used
  2. Providing an object when one is requested (using Get())
  3. Instantiating and adding objects to the pool when needed
  4. Returning objects to the pool when they’re disabled.

Pool.cs

The PooledMonobehaviour base class

The PooledMonobehaiour is a base class that any pooled objects 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! 🙂

Continue reading >
Share

Improving the Unity Editor Inspector with Unity Attributes

By Jason Weimann / May 22, 2017

Unity has a variety of Property Attributes you can use to make the inspector easier to use, save you time, and prevent mistakes.  Using these Unity Attributes, you can clamp values to acceptable ranges, customize Color settings, or even quickly add custom actions to your inspector window.

Today, we’ll cover some of the commonly used Unity Attributes to show both when and how to use them.

SerializeField

The first and most talked about attribute is [SerializeField].  The [SerializeField] attribute tells the editor to make a private field visible in the inspector.  Why would you want to use this instead of making the field public?  Encapsulation! 🙂

I actually cover that in detail here: Editing Unity variables – Encapsulation & [SerializeField] so I won’t re-explain how important it is now.

SelectionBase

The SelectionBase attribute is one of my favorites and probably one of the most overlooked.  If you’ve ever setup a gameobject where all the meshes are children of your actual object you’ve probably been frustrated trying to click the object in the scene view.  Without this attribute, the child with the mesh will take the selection, then you get to dig through the hierarchy and select the parent.

SelectionBase fixes that situation and makes selecting your gameobject easy.  Simply add the [SelectionBase] attribute to your monobehaviour and next time you click on the object, the attributed object will be selected.

To see this in action, watch how the parent gameobject is selected when I’ve added a component that contains the [SelectionBase] attribute.

Code

Range

The Range attribute allows you to set acceptable ranges for your numeric fields.  Maybe you’re working with a spawn or reload timer and only positive values are acceptable.  By adding the [Range] attribute, you can limit the values in the inspector and provide a good indication of reasonable values with the slider.

 
Code

Text Area & MultiLine

The [TextArea] Attribute tells the editor you want a textbox.  This is useful for longer strings like dialog text or descriptions.  The [MultiLine] attribute is similar but places the textbox on the right side instead of below the label.

 

Code

ColorUsage

The [ColorUsage] attribute isn’t one I’ve used much personally.  It allows you to set some constraints on a color picker, like disabling the alpha channel or setting minimum and maximum brightness values.

Headers & Spacing

You can organize your variables into groups easily with the [Header] attribute.  Just put it above the first field you want in the group.  Don’t add it to each item though, it’s not a grouping mechanism and only creates a header before that field is rendered.

You can see below how I’ve organized all my examples into separate areas using the [Header] attribute.  And if you just want to add a little spacing without a header, the [Space] attribute will accomplish that for you (look between the two sliders)

Code

You can see on line 1 I create a header called “Numeric Attributes”

On line 7, I’ve added the [Space] attribute to put a tiny space between the sliders.

ContextMenuItem

The ContextMenuItem attribute allows you to create a right click context menu on the label of a specific field.  Add the attribute with the text and method name to call, and when you right click on the field you’ve attributed, you’ll see the dialog like this.

Code

ContextMenu

You can also add a context menu for the entire component.  To do that, you’ll attribute a method instead of a field.  You can access and execute the method from the editor by right clicking or using the gear.

Code

Conclusions

The Unity editor is an amazing tool.  Attributes are helpful… Use them.. 🙂

 

Also if you want the complete sample code, it’s right here:

 

Continue reading >
Share
1 12 13 14 15 16 21
Page 14 of 21