All posts in "C#"

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

Pooled Decals for Bullet Holes

The Bullet Decal Pool System

Todays article came out of necessity.  As you probably know, I’m wrapping up my long awaited VR Course, and one of the last things I needed to create is a decal setup for the game built in it.  To do decals properly, you’d want a full fledged decal system, but for this course and post, we have a system that does exactly what we need and no more.

What is that?  Well it’s a system to create a bullet hole decal where you shoot.  And do to it without creating and destroying a bunch of things at runtime.

It’s worth noting that I wrote this system for a VR game, but it is completely applicable to a normal game. This would work in a 3d game, mobile game, or anything else that needs basic decals.

The end result will look something like this

How do we build it?

Let’s take a look at the code

Code Breakdown

Serialized Fields

We open with 2 serialized fields.

bulletHoleDecalPrefab – The first determines which decal prefab we’ll use.  If you’re building a more generic decal system, you may want to re-name this.  Because it’s part of a VR course, I left the name as is, but if I were putting this in another game, it’d likely be more generic or maybe even an array that’s randomly chosen from.

maxConcurrentDecals – This sets the maximum number of decals the system will show.  We do this primarily for performance, but also to avoid visual cluttering.  Having too many decals could cause a hit on rendering, remember each one is a transparent quad.  This number is variable in the editor though, so you can adjust it as you see fit for your game.

 

Private Fields

We have two private fields in this class.  They’re both using the Queue type to keep a first in first out collection of decals.

decalsInPool – This is where we’ll store the decals that are available and ready to be placed.

decalsActiveInWorld – These are the decals that we’ve placed in the world.  As our pool runs empty, we’ll start grabbing decals from here instead.

 

Awake

Calls our InitializeDecals method()….

 

Private Methods

InitializeDecals() – This is our setup.  Here, we create our queues, then we use a loop to create our initial pooled decals.

InstantiateDecal() – Here we do the actual creation of a single decal.  This is only called by InitializeDecals & a special editor only Update you’ll see soon.

GetNextAvailableDecal() – This method gets the next available decal…. useful description eh’?  It actually just looks at the pool, if there’s at least one decal in it, the method returns the first one in the queue.  If there’s no decal in the pool, it returns the oldest decal that’s active in the world.

 

Public Methods

SpawnDecal(RaycastHit hit) – This is our only public method, it’s the one thing this class is responsible for doing.  In the code that calls it, we’re doing a raycast to determine where our bullet hits.  The raycast returns a raycasthit and we pass it into this method as the only parameter.

The method uses GetNextAvailableDecal() and assuming a decal is available, it places that decal at the raycasthit.point, adjusts the rotation to the raycasthit.normal, and sets the decal to active.  The method ends by adding the decal to the decalsActiveInWorld queue.

 

#if UNITY_EDITOR ????

Everything else in this class is actually wrapped to only run in the editor.

This code has a single purpose, to update our queue size at runtime.

It’s absolutely not necessary for your decal system, but it’s a nice little thing I enjoy having 🙂

I won’t cover each method, but you should play with the queue size at run-time and watch as it keeps everything in sync.

 

 

 

Continue reading >
Share

Unity OnInspectorGUI – Custom Editors, Gizmos, and Spawning Enemies

By Jason Weimann / September 12, 2016

Creating games can be difficult and time consuming.  You have to code all kinds of systems, add and modify art and sound, and of course design levels.

As a programmer, I often found myself overlooking level design, and forgetting just how time consuming and frustrating it could be.

But I also know that as a programmer, there are things I can do to make it easier for myself (and any designers working on the games).

Today, I’ll show  you one very useful technique you can use to drastically reduce the time spent on design work, while making it a much more fun process.

The Example – Spawn Points

Enemies are a very common thing in video games, and in a large number of them, enemies are created/spawn throughout the game.

The GameObject spawning them could be simple, instantiating an enemy on a set interval.

Before I show you my technique, let me show you how I used to create them.

Version 1 – A simple transform (very bad)

When I first started placing spawn points in a game, I did it by simply placing a transform.  The screenshot below is actually a step beyond what I used to do, because in this one I’ve actually enabled the Icon so you can see it.

Custom Editors - Spawn Point as Transform

If you haven’t used the Icons before, the selection dialog is just to the left of the Active checkbox in the inspector.

Custom Editors - Icon Selector

I quickly moved on from just placing a transform though because it got really hard to tell exactly where the spawn point was in the world.  If the transform is below the ground, I wouldn’t be able to tell without moving the camera all around.  The same goes for a spawn point that’s in a building, hovering over the ground, etc.

Version 2 – Using a cube (less bad)

The next evolution of my spawn points involved cubes.  Creating spawn points with a cube renderer mostly resolved the issue with not being able to easily see the position in the scene.

To make this work though, I needed my spawn points to disable the renderer in their Awake() call so I didn’t have random boxes showing in the world when the game was being played.

It also didn’t really solve the issue of spawning enemies on the ground, so I’d have to make my spawners do a raycast downward to the ground to get their spawn point before popping out an enemy.

I’d try to place the boxes just a bit over the ground, but found that I wasted a lot of time lining things up right, testing, making minor movements, testing, etc.

In addition to that, it felt ugly, but I used this technique for a very long time….

Custom Editors - Spawn Point as Cube

Version 3 – Custom Editors

After using the previous methods for way too long, I finally came up with a solution that solved my previous problems and made building levels much faster.

Custom Editors - Enemy Spawners Scene View

As you can see in the image, Version 3 looks drastically different.  There are colored spheres with lines attaching them.  There’s text over them instead of in an Icon, and that text has a lot of info to it.

Before I show you how it’s done, let me explain what it is you’re seeing.

The Green spheres show actual spawn points for this game.  These are points where enemies will be instantiated.

The Blue spheres are waypoints.  Enemies spawn at the green spheres then walk to the blue ones.

The lines between them show which waypoints belong to each spawnpoint.

What’s that Text?

The text over the spawn point shows a few things.  Let’s examine the top left spawn point.

Custom Editors - Spawn Point Up Close

Intro 1 0:25-0:28 Spawn 2 [1/3] after 5(8s)

Intro 1 – This is the name of the wave/area this spawn point belongs to.  In this case, it’s the first introductory wave the player gets when they start the game.

0:25-0:28 – Here you see the time in the wave that this spawn point will be active.  This spawn point is active for a very short time, starting 25 seconds into the wave and ending only 3 seconds later.

Spawn 2 [1/3] – This tells us how many enemies will spawn from this point.  It’s going to spawn 2 zombies, one every three seconds (the [1/3] shows the count and interval).  The first one will spawn immediately, and the second after 3 seconds.

after 5 – This part isn’t visible on all spawn points, only on spawn points that delay their start.  You can see that in the Hierarchy, this spawn point is under a gameobject that enables after 20 seconds.  Each spawnpoint in a timer can have an additional delay added to them to avoid a large list of timers in the hierarchy.  The 5 second delay is what makes this spawner start at 0:25 instead of 0:20.

Custom Editors - Hierarchy

(8s) – The last thing you see just shows how long this spawnpoint is enabled.  For this one, after 8 seconds it will auto disable itself.  This is just time of the last spawn minus the time the spawn point becomes enabled (28 – 20 in this case). 

Snapping to the Terrain or Navmesh

One final benefit of this system that I want to show before getting into code is the ability to have your spawn points and waypoints automatically snap to the terrain or navmesh.  In the example below, you can see that when I move this waypoint around it will automatically find its place on the ground as soon as I release it.

This saves a ton of time and resolves that entire issue of lining things up.  Don’t do these things manually, have the editor do it for you.

Custom Editors - Waypoint Snapping

How It Works

To make my custom spawn points work like they do, I take advantage of two great features in Unity, Gizmos and Custom Inspectors.

Both parts do about half of the work required to get the full functionality.

Let’s start with this snippet from my EnemySpawner.cs script

The first thing we do here is get the Wave parent of this spawner.  This is the GameObject that all spawners and timers will be under for a specific wave or area of the game.

In the example above, you saw the green part “Intro 1“.  That part was just the name of the wave we find right here.

Line 6 takes this wave name and formats uses string.Format to split the wave name from the current spawners name, which is why “Intro 1” is above the spawning details.

On Line 8, we check to see if the wave this gizmo is for is currently selected.  We then use that to determine if we want a green spawner gizmo or a gray one.  I do this so we can easily tell which spawners are related.  All spawners in a wave will be colored at the same time, and all the ones from other waves will just show up as gray.

Custom Editors - Disabled Spawners

Line 12 draws the sphere using Gizmos.DrawSphere, in whichever color we’ve chosen.

Lines 14-15 will draw the final text above the sphere if the spawner is in the selected wave.

The OnDrawGizmos code is pretty short, and on it’s own it does a bit of really useful stuff, but there’s a lot missing.  It does show the spheres, and it places the name above the sphere with the wave name as a prefix, but there’s a lot more we want to happen.

For example the label from line 15 has a lot of useful info, and we pull that from the name, but we don’t want to manually enter that info, we want it auto generated and updated whenever we change things.

Overriding ToString()

To generate the name, with all the useful data, we override the ToString method of our EnemySpawner class.

If you’ve never overridden the ToString method, you may want to check out this description for a simpler sample of how it works https://msdn.microsoft.com/en-us/library/ms173154.aspx

Every object in c# implements the ToString method that you can override (the default return value for most objects is the name of the class/type).

In this example, we’re building up the rest of the label text.  While I won’t go into the details of each line, the end result of this method looks like this:

"0:25-0:28 Spawn 2 [1/3] after 5(8s)"

The Custom Editor

To tie this all together, we use a custom editor for the EnemySpawner.

Before you see the bigger parts of the script, let’s start with the initial attribute that tells Unity this class is a custom editor.

The CustomEditor attribute allows you to tell the engine which MonoBehaviour you want the editor to be used for.  This is specified by giving it the type of the MonoBehaviour.  In this example it’s typeof(EnemySpawner).

Also remember to add the using UnityEditor statement and make the base class for your custom editor be of typeEditor“.

The Editor class has one important method you need to override.  Check out this expanded version of the script and the OnInspectorGUI method that’s being overridden.

This method is called every frame in the editor while the Inspector window is visible and the object is selected.  If the Inspector is not visible, or is showing some other game object, this code won’t be called.

Code Breakdown

The first thing we do in this OnInspectorGUI method is cache the component we’re working with.

On line 12, we assign the target gameobject to the _enemySpawner variable.

The variable target is defined by the editor class and specifies the gameobject this editor is showing currently

Line 13 calls the base editor class version of OnInspectorGUI so it can handle anything that we’re not dealing with.  This is required because we’re overriding the behavior of OnInspectorGUI.

Lines 14-19 are a single method call to create a range slider that will fill the min and max movement speed.  I do this just to enforce the idea that the max must be greater than the minimum.  As a benefit, it also makes the value a little easier to visualize.

custom-editors-movementspeed-range-slider

Lines 21-24 are there to add waypoints to the spawners.  I won’t cover in detail how they work, but these buttons essentially add a child object that will be used as a waypoint.  If it’s a random waypoint, my navigation code will select one at random, if it’s static, the enemies will path around them in order.  These also have their own gizmo and custom editor code to make them show up as blue in the scene view.

Line 28 just calls a method to disable any left over colliders or renderers on the spawner.  Generally there aren’t any, but sometimes one gets created with a cube or sphere and I want to make sure that’s disabled right away.  I could just remove them here too, but disabling does the same job and feels safer.

Line 30 does one of the most important parts.  It calls the method to stick the spawner to the ground.  Sticking the spawner down is done by a raycast from the spawners current position aimed downward.  We get the hit point and update the spawners position.

Line 33 wraps it all up by updating the spawners name.  It uses the overridden ToString() method we created above to determine the objects new name.

Auto Naming in Action

custom-editors-naming-in-action

Important Note

For a custom editor to work, you need to place the script in a sub-folder named “Editor“.  This sub-folder can be anywhere in your project, and you can have multiple Editor folders, but only scripts in an Editor folder will work.

Custom Editors - EditorFolder

Custom Editors - EnemySpawner

Continue reading >
Share

Unity Interfaces

By Jason Weimann / September 4, 2016

Unity Interfaces – Getting Started

Lately, I’ve realized that many Unity developers have never programmed outside of Unity projects.
While there’s nothing wrong with that, it does seem to leave some holes in the average Unity developers skill set.
There are some great features and techniques that aren’t commonly used in Unity but are staples for typical c# projects.

That’s all fine, and they can be completely productive, but some of the things I see missing can really help, and I want to make sure to share those things with you.

Because of this, I’ve decided to write a few articles covering some core c# concepts that can really improve your code if you’re not using them already.

The first in this series will cover c# interfaces.

If you google c# interfaces, you’ll come across the msdn definition

An interface contains definitions for a group of related functionalities that a class or a struct can implement.

Personally, I prefer to use an example to explain them though, so here’s one from an actual game.

The ICanBeShot interface

In Armed Against the Undead, you have guns and shoot zombies..Armed Against the Undead
But you can also shoot other things like Ammo pickups, Weapon unlocks, Lights, etc.

Shooting things is done with a standard raycast from the muzzle of the gun.  Any objects on the correct layer and in range can be shot.

If you’ve used Physics.Raycast before, you’ll know that it returns a bool and outputs a RayCastHit object.

The  RayCastHit has a .collider property that points to the collider your raycast found.

In Armed, the implementation of this raycast looks like this:

private bool TryHitEnvironment(Ray ray)
{
	RaycastHit hitInfo;

    if (Physics.Raycast(ray, out hitInfo, _weaponRange, LayerMask.GetMask("EnvironmentAndGround")) == false)
        return false;

    ICanBeShot shootable = hitInfo.collider.GetComponent<ICanBeShot>();

    if (shootable != null)
		shootable.TakeShot(hitInfo.point);
    else
        PlaceBulletHoleBillboardOnHit(hitInfo);

    return true;
}

Here you can see that we do a raycast on the EnvironmentAndGround layer (where I place things you can shoot that aren’t enemies).

If we find something, we attempt to get an ICanBeShot component.

That component is not an actual implementation but rather an Interface which is on a variety of components.

It’s also very simple with a single method named TakeShot defined on it as you can see here:

public interface ICanBeShot
{
    void TakeShot(Vector3 hitPosition);
}

If you’ve never used an interface before, it may seem a little strange that there’s no actual code or implementation.  In the interface, we only define how the methods look and not the implementation.  We leave that part to the classes implementing our interface.

How the Interface is used

So now that I have my interface, and I have a method that will search for components implementing that interface, let me show you some of the ways I’m using this interface.

Implementation #1 – Ammo Pickups

public class AmmoBox : MonoBehaviour, ICanBeShot
{
    public void TakeShot(Vector3 hitPosition)
    {
		PickupAmmo();

		if (_isSuperWeaponAmmo)
			FindObjectOfType<Inventory>().AddChargeToSuperWeapon();
		else
			FindObjectOfType<Inventory>().AddAmmoToWeapons();
	}
}

This ammo script is placed on an Ammo prefab.

Ammo Scene and Inspector

Ammo Scene and Inspector

Notice the box collider that will be found by the raycast in TryHitEnvironment above (line 5).

 

Ammo Inspector

Ammo Inspector

In the case of the AmmoBox, the TakeShot method will add ammo to the currently equipped weapon.  But an AmmoBox isn’t the only thing we want the player to shoot at.

Implementation #2 – Weapon Unlocks

public class WeaponUnlocker : MonoBehaviour, ICanBeShot
{
    public void TakeShot(Vector3 hitPosition)
    {
        WeaponUnlocks.UnlockWeapon(_weaponToUnlock);
        PlayerNotificationPanel.Notify(string.Format("<color=red>{0}</color> UNLOCKED", _weaponToUnlock.name));

        if (_particle != null)
            Instantiate(_particle, transform.position, transform.rotation);

        Destroy(this.gameObject);
    }
}

Compare the AmmoBox to the WeaponUnlocker.  Here you see that we have a completely different implementation of TakeShot.  Instead of adding ammo to the players guns, we’re unlocking a weapon and notifying the player that they’ve unlocked it.

And remember, our code to deal with shooting things didn’t get any more complicated, it’s still just calling TakeShot.  This is one of the key benefits, we can add countless new implementations, without complicating or even editing the code to handle shooting.  As long as those components implement the interface, everything just works.

Implementation #3 – Explosive Boxes

These are crates that when shot will explode and kill zombies.

Implementation #4 – Destructible Lights

In addition to everything else, the lights can also take a shot (in which case they explode and turn off the light source component)

Recapping

Again to make the benefits of Unity interfaces clear, re-examine our code in TryHitEnvironment.

ICanBeShot shootable = hitInfo.collider.GetComponent<ICanBeShot>();

if (shootable != null)
	shootable.TakeShot(hitInfo.point);

We simply look for any collider on the right layer then search for the ICanBeShot interface.  We don’t need to worry about which implementation it is.  If it’s an ammo box, the ammo box code will take care of it.  If it’s a weapon unlock, that’s covered as well.  If we add a new object that implements the interface, we don’t need to touch our current code.

Other Benefits

While I won’t cover everything that’s great about interfaces in depth here, I feel I should at least point out that there are other benefits you can take advantage of.

  1. Unit Testing – If you ever do any unit testing, interfaces are a key component as they allow you to mock out dependencies when you write your tests.
  2. Better Encapsulation – When you code to interfaces, it becomes much more obvious what should be public, and your code typically becomes much better encapsulated.
  3. Loose Coupling – Your code no-longer needs to rely on the implementations of methods it calls, which usually leads to code that is more versatile and changeable.

 

 

Continue reading >
Share

Unity Coding Standards

Today, we’ll talk about Unity Coding Standards.  We’ll cover things to do, things to avoid, and general tips to keep your projects clean, maintainable, and standardized.

Things to avoid

I want to prefix this by saying that the thoughts in this post are guidelines and not meant to be a criticism of anyone.  These are personal preferences and things I’ve picked up from experience across a variety of different projects.

If you find that you commonly do and use some of these things, don’t be offended, just try to be conscious of the issues that can arise.  With that little disclaimer, here are some of the key things I always fight to avoid and recommend you do your best to limit.

Public Fields

I won’t go deep into this as I think I’ve already covered it here.  Just know that public fields are generally a bad idea.  They often tend to be a precursor to code that’s difficult to read and maintain.

If you need to access something publicly, make it a property with a public getter.  If you really need to set it from another class, make the setter public too, otherwise use a property that looks like this:

public string MyStringThatNeedsPublicReading { get; private set; }

Large Classes

I’ve seen far too many Unity projects with class sizes that are out of control.  Now I want to clarify that this is not something only specific to unity, I’ve seen classes over 40k lines long in some AAA game projects.  I’ve seen .cs & .js files in web apps over 20k lines long.

That of course does not make them right or acceptable.

Large classes are hard to maintain, hard to read, and a nightmare to improve or extend.  They also always violate one of the most important principals in Object Oriented Programming.  The principal of Single Responsibility.

As a general rule I try to keep an average class under 100 lines long.  Some need to be a bit longer, there are always exceptions to the rules.  Once they start approaching 300 lines though, it’s generally time to refactor.  That may at first seem a bit crazy, but it’s a whole lot easier to clean up your classes when they’re 300 lines long than when they reach 1000 or more.  So if you hit this point, start thinking about what your class is doing.

Is it handling character movement?  Is it also handling audio?  Is it dealing with collisions or physics?

Can you split these things into smaller components?  If so, you should do it right away, while it’s easy.

Large MethodsCoding Standards - too long list

Large classes are bad.  Large methods are the kiss of death.

A simple rule of thumb: if your method can’t fit on your screen, it’s too long.  An ideal method length for me is 6-10 lines.  In that size it’s generally doing one thing.  If the method grows far beyond that, it’s probably doing too much.

Some times, as in the example below, that one thing is executing other methods that complete the one bigger thing.  Make use of the Extract Method refactoring, if your method grows too long, extract the parts that are doing different things into separate methods.

Example

Take this Fire() method for example.  Without following any standards, it could easily have grown to this:

Original

protected virtual void Fire()
{
	if (_animation != null && _animation.GetClip("Fire") != null)
		_animation.Play("Fire");

	var muzzlePoint = NextMuzzlePoint();
	if (_muzzleFlashes.Length > 0)
	{
		var muzzleFlash = _muzzleFlashes[UnityEngine.Random.Range(0, _muzzleFlashes.Length)];

		if (_muzzleFlashOverridePoint != null)
			muzzlePoint = _muzzleFlashOverridePoint;

		GameObject spawnedFlash = Instantiate(muzzleFlash, muzzlePoint.position, muzzlePoint.rotation) as GameObject;
	}

	if (_fireAudioSource != null)
		_fireAudioSource.Play();

	StartCoroutine(EjectShell(0f));

	if (OnFired != null) OnFired();

	if (OnReady != null)
		OnReady();

	var clip = _animation.GetClip("Ready");
	if (clip != null)
	{
		_animation.Play("Ready");
		_isReady = false;
		StartCoroutine(BecomeReadyAfterSeconds(clip.length));
	}

	_currentAmmoInClip--;
	if (OnAmmoChanged != null)
		OnAmmoChanged(_currentAmmoInClip, _currentAmmoNotInClip);

	RaycastHit hitInfo;

	Ray ray = new Ray(muzzlePoint.position, muzzlePoint.forward);
	Debug.DrawRay(muzzlePoint.position, muzzlePoint.forward);

	if (TryHitCharacterHeads(ray))
		return;

	if (TryHitCharacterBodies(ray))
		return;

	if (OnMiss != null) OnMiss();

	if (_bulletPrefab != null)
	{
		if (_muzzleFlashOverridePoint != null)
			muzzlePoint = _muzzleFlashOverridePoint;
		Instantiate(_bulletPrefab, muzzlePoint.position, muzzlePoint.rotation);
	}
}

This method is handling firing of weapons for an actual game.  If you read over it, you’ll see it’s doing a large # of things to make weapon firing work.  You’ll also notice that it’s not the easiest thing to follow along.  As far as long methods go, this one is far from the worst, but I didn’t want to go overboard with the example.

Even so, it can be vastly improved with a few simple refactorings.  By pulling out the key components into separate methods, and naming those methods well, we can make the Fire() functionality a whole lot easier to read and maintain.

Refactored

    protected virtual void Fire()
	{
		PlayAnimation();

		var muzzlePoint = NextMuzzlePoint();
		SpawnMuzzleFlash(muzzlePoint);

		PlayFireAudioClip();
		StartCoroutine(EjectShell(0f));

		if (OnFired != null) OnFired();
		HandleWeaponReady();

		RemoveAmmo();

		if (TryHitCharacters(muzzlePoint))
			return;

		if (OnMiss != null) OnMiss();

		LaunchBulletAndTrail();
	}

With the refactored example, a new programmer just looking at the code should be able to quickly determine what’s going on.  Each part calls a method named for what it does, and each of those methods is under 5 lines long, so it’s easy to tell how they work.  Given the choice between the 2 examples, I’d recommend #2 every time, and I hope you’d agree.

CasingCasing

The last thing I want to cover in this post is casing.  I’ve noticed in many projects I come across, casing is a mess.  Occasionally, project I see have some kind of standard they’ve picked and stuck to.  Much of the time though, it’s all over the place with no consistency.

The most important part here is to be consistent.  If you go with some non-standard casing selection, at least be consistent with your non-standard choice.

What I’m going to recommend here though is a typical set of C# standards that you’ll see across most professional projects in gaming, business, and web development.

Classes

Casing: Pascal Case

public class MyClass : MonoBehaviour { }

Methods

Casing: Pascal Case (No Underscores unless it’s a Unit Test)

private void HandleWeaponReady()

Private Fields

Coding Standards - Private FieldCasing: camelCase – with optional underscore prefix

// Either
private int maxAmmo;
// OR my prefered
private int _maxAmmo;

This is one of the few areas where I feel some flexibility.  There are differing camps on the exact naming convention to be used here.

Personally, I prefer the underscore since it provides an obvious distinction between class level fields and variables defined in the scope of a method.

Either is completely acceptable though.  But when you pick one for a project, stick with it.

Public Fields

It’s a trick, there shouldn’t be any! 😉

Public Properties

Casing: Pascal Case

public int ReaminingAmmoInClip { get; private set; }

These should also be Automatic Properties whenever possible.  There’s no need for a backing field like some other languages use.

Again you should also mark the setter as private unless there’s a really good reason to set them outside the class.

 

Wrap Up

Again, this is just a short list of a few things that I think are really important and beneficial for your projects.  If you find this info useful, drop in a comment and I’ll work to expand out the list.  If you have your own recommendations and guidelines, add those as well so everyone can learn and grow.
Thanks, and happy coding!

Continue reading >
Share

Unity Baseball Bat Physics

If you’ve been following the site, you may have noticed the VR Baseball game.  While this was an interesting project, there was one part that stood out as particularly worthy of writing about.  In this article, I’ll show you how to setup physics in your own baseball, cricket, or other batting style game in Virtual Reality.  We’ll use a simple trick to make the batting feel real and fun.

Video Version

The Game

In VR Baseball, the goal is simple. A ball is pitched, you swing the bat, and if you hit, the ball goes flying.

The Problem

The first implementation of VR Baseball had a very simple batting system. There was a colider on the bat and the ball had some bounciness. Choosing a level would just adjust the bounciness factor of the ball by switching out the PhysicsMaterial on the balls Collider. It was simple, it worked, but it felt weird. The main issue was that no-matter where on the bat you hit, the ball flew the same speed.

You could hit it with the handle, it’d go flying. You could push forward with the bat and get a home run off the tip. The only thing that was taken into account was the velocity of the bat at the time.

Now in most situations, you don’t need to worry about the velocity of the exact part where your collisions happen, only the general velocity of the object it’s colliding with.  But with baseball, we have a swinging action, and we need the velocity at the end of the bat to be different from the velocity at the handle (just like real life).

The Solution

Instead of having the baseballs collide with the bat, we spawn some new objects to collide with.
The bat has a set of child objects that determine where these new objects will spawn and be at run-time.
Bat Capsules

As you can see, the BatCapsules don’t have much to them.  They’re really just a script and a transform.  There’s a collider and a mesh renderer, but those are only for debugging and visualizing, which is why they’re disabled normally (I would toggle them on when the follower seemed to be in the wrong spot, so I could verify the location I was giving them was valid).

BatCapsule Inspector

The most important part though is the “Bat Capsule” script on them.

using UnityEngine;

public class BatCapsule : MonoBehaviour
{
    [SerializeField]
	private BatCapsuleFollower _batCapsuleFollowerPrefab;

	private void SpawnBatCapsuleFollower()
	{
		var follower = Instantiate(_batCapsuleFollowerPrefab);
		follower.transform.position = transform.position;
		follower.SetFollowTarget(this);
	}

	private void Start()
	{
		SpawnBatCapsuleFollower();
	}
}

The method SpawnBatCapsuleFollower() does exactly what its name implies.  It spawns a BatCapsuleFollower, and calls a single initialization method named SetFollowTarget.  We pass “this” into SetFollowTarget() as we want the BatCapsuleFollower to follow this object which is attached to the bat.

The Start() method in this script does a single thing, it calls SpawnBatCapsuleFollower().  We do this so anyone reading the code later can tell exactly what we want to do, without needing comments.

 

using UnityEngine;

public class BatCapsuleFollower : MonoBehaviour
{
    private BatCapsule _batFollower;
	private Rigidbody _rigidbody;
	private Vector3 _velocity;

	[SerializeField]
	private float _sensitivity = 100f;

	private void Awake()
	{
		_rigidbody = GetComponent<Rigidbody>();
	}

	private void FixedUpdate()
	{
		Vector3 destination = _batFollower.transform.position;
		_rigidbody.transform.rotation = transform.rotation;

		_velocity = (destination - _rigidbody.transform.position) * _sensitivity;

		_rigidbody.velocity = _velocity;
		transform.rotation = _batFollower.transform.rotation;
	}

	public void SetFollowTarget(BatCapsule batFollower)
	{
		_batFollower = batFollower;
	}
}

The BatCapsuleFollower script is responsible for following the bat capsule…

The work for that is done in FixedUpdate().  To follow the BatCapsule, it gets the position it wants to be in, then subtracts it from the current position.  That distance is multiplied by a sensitivity value that can be adjusted in the editor.  For my game, I found a value of about 50 worked well.  It sets the rigidbody velocity to that calculated value which makes it move toward the BatCapsule.

Next it adjusts the rotation to match the BatCapsule.  If we don’t do that, it will end up sideways.

Important – Physics Layers

When setting up your BatCapsuleFollower, make sure the Layer it’s on does not collide with itself.  If you don’t, the BatCapsuleFollowers will be bouncing off each other, not doing what you want.Physics Menu

To get to the physics settings, click Assets->Project Settings->Physics

Physics Menu

In here, you need to make sure the layer you’ve chosen for your BatCapsuleFollowers (please put them on their own layer), does not collide with itself.  It should also not collide with anything other than the ball (unless there’s something else you want to hit).  You can see I’ve set mine up to do exactly that.

Physics Grid

Conclusion

With it setup like this, the BatCapsuleFollowers will move at different velocities, causing the outer most one to hit much further than the innermost.  While this could be further tuned to make a real sweet spot on the bat, I’ve found that this functionality works well enough.

Project Download

https://unity3dcollege.blob.core.windows.net/site/Downloads/VR%20Baseball%20Physics.zip

Get Some Bats

A good friend of mine made the awesome bats featured here and they’re available on the asset store.  If you wanna do some baseball stuff and support him, go grab one now 🙂

https://www.assetstore.unity3d.com/en/#!/search/page=1/sortby=popularity/query=publisher:20410

Continue reading >
Share

Unity 3D Workshop: Introduction and Building your First Game

http://www.meetup.com/San-Diego-Unity-3D-Developers-Meetup-Art-Design-Development/events/229773349/

I’m teaching an intro to Unity session on 4/5 with the San Diego Unity Usergroup.  If you’ve never used unity or maybe opened the editor, got lost, and quit out, this session is for you.

We’ll go over the basics of building a 3D game (no 2D stuff in this session), and build a foundation for something bigger in the future.

Bring a laptop with Unity 5.3x installed and follow along, or pair up with someone else as we go through a variety of subjects including gameplay, physics, collision, and navigation.

When you leave, you should have the base for a game and the understanding to extend it in a variety of ways.

I look forward to seeing you there!

Continue reading >
Share

Dependency Injection and Unit Testing Unity

This post will be the first in what will likely be a long series. Dependency Injection and Unit Testing are generally considered staples in modern software development. Game development for a variety of reasons is one of the few areas where this isn’t true. While it’s starting to become more popular, there are quite a few things holding back game programmers from embracing these valuable paradigms.

I’d like to open by giving a quick description of the benefits you’ll gain by embracing dependency injection.  Before you jump away thinking “I don’t need this” or “this will be too complicated”, just take a look at what you have to gain.  And let me try to quell any fears, this is something you can definitely take advantage of, it won’t be hard, it’ll save you time, and your code will be improved.

 

Benefits – What do I have to gain?

Loose Coupling

Dependency Injection by it’s nature encourages very loose coupling.  This means your objects and classes don’t have tight dependencies on other classes.  Loose coupling leads to having code that is much less rigid and brittle.

Re-usbility Across Projects

Loose coupling also makes your classes much easier to use across projects.  When your code has dependencies on many other classes or static global variables, it’s much harder to re-use that code in other projects.  Once you get into the habit of good separation and dependency injection, you’ll find that reuse becomes a near trivial task.

Encourages Coding to Interfaces

While you can certainly code to interfaces without Dependency Injection, using it will naturally encourage this behavior.  The benefits of this will become a bit more obvious in the example below, but it essentially allows you to swap behavior and systems in a clean way.

Cleaner Code

When you start injecting your dependencies, you quickly end up with less “spaghetti-code”.  It becomes much clearer what a classes job is, and how the class interacts with the rest of your project.  You’ll find that you no-longer have to worry about a minor change in one piece of code having an unexpected consequence in something that you thought would be completely unrelated.

As an example, once while working on a major AAA MMO game, I saw a bug fix to a specific class ability completely break the entire crafting system.  This exactly the kind of thing we want to avoid.

Unit Testing

This is one of the most commonly stated benefits to Dependency Injection.  While it’s a huge benefit, you can see above that it’s not the only one.  Even if you don’t plan to unit test initially (though you should),  don’t rule out dependency injection.

If you haven’t experienced a well unit tested project before, let me just say that it’s career changing.  A well tested project is less likely to slip on deadlines, ship with bugs, or fail completely.  When your project is under test, there’s no fear when you want to make a change, because you know immediately when something is broken.  You no-longer need to run through your entire game loop to verify that your changes work, and more importantly that you haven’t broken other functionality.

 

 

If it’s so good, why isn’t this common place?

Now, I’d like to cover a few of the reasons the game industry has been slow to adopt Dependency Injection & Unit Testing.

C++

While this doesn’t apply to Unity specifically, the game industry as a whole has primarily relied on C++. There were of course studios that developed in other languages, but to this date, outside of Unity, the major engines are all C++ based. C++ has not had nearly the same movement towards Dependency Injection or Unit Testing as other common enterprise languages (Java, C#, JS, Ruby, etc).  This is changing though, and with the proliferation of unit testing and dependency injection in C#, it’s the perfect time to jump in with your games.

Performance

Dependency Injection adds overhead to your game. In the past, that overhead could be too much for the hardware to handle.  Given the option between 60fps and dependency injection, 60fps is almost always the correct answer.  Now though, hardware is really fast, and 99% of games can easily support Injection without giving up any performance.

Mindset

While there are countless other “reasons” you could come across from game programmers, the key one is just an issue of mindset.  Too many people have been programming without Injection and Unit testing and just haven’t been exposed to the benefits.  They think “that’s for enterprise software”, “that’s something web developers do”, or “that doesn’t work for games”.  My goal here is to convince you that it’s worth trying.  I promise if you dig in and try dependency injection and unit testing, you’ll quickly start to see the benefits, and you’ll want to spread the word as well.

 

Dependency Injection Frameworks

When you’re searching, you may also see the DI frameworks referred to as IOC containers.

You may be wondering how you get started with Dependency Injection in Unity.  It’s not something built into the Unity engine, but there are a variety of options to choose from on GitHub and in the Asset Store.

Personally, I’ve been using Zenject, and my samples will be done using it.  But that doesn’t mean you shouldn’t look into the other options available.

Zenject

I think the description provided on the Zenject asset page does a better job describing it than I could, so here it is:

Zenject is a lightweight dependency injection framework built specifically to target Unity. It can be used to turn the code base of your Unity application into a collection of loosely-coupled parts with highly segmented responsibilities. Zenject can then glue the parts together in many different configurations to allow you to easily write, re-use, refactor and test your code in a scalable and extremely flexible way.

While I hope that after reading this series you have a good idea why you should use a dependency injection framework, and how to get started, I must highly recommend you take a look at the documentation provided on the Zenject GitHub page.

Constructor Injection

Most Dependency Injection is done via what’s called Constructor Injection.  This means that anything your class relies on outside itself is passed in via the constructor.

Example

I want to give an example of how you’d use Constructor Injection in a more general sense before diving too deep into the differences with Unity.  What I’m presenting here is a simplified version of a game state system I’m using in a Unity project currently.

In my project, I have a variety of game state classes.  The different “GameStates” handle how the game functions at different stages throughout the game cycle.  There are game states for things like generating terrain, lost/gameover, building, attacking, and in this example, ready to start.

In the game state “ready to start“, all we want to do is wait for the user to start the game.  The game state doesn’t care how the user starts the game, only that they do.  The simplest way to implement this would be to check on every update and see if the user pressed the “Fire1” button.

It may look something like this:

using UnityEngine;

public class GameStateReadyToStart : MonoBehaviour
{
    void Update()
	{
		if (Input.GetButton("Fire1"))
			SwitchToNextGameState();
	}

	private void SwitchToNextGameState()
	{
		// Logic to go to next gamestate here
	}
}

This will work, it’s simple, and quick to implement, but there are some issues with it.

 

Problems

  • Our gamestate is a monobehaviour so we can read the input during the update.
  • The Input logic is inside a class who’s job isn’t Input.  The gamestate should handle game state/flow, not input.
  • Changing our input logic requires us to touch the gamestate class.
  • We’ll have to add input logic to every other gamestate.
  • Input can’t be easily varied across different devices.  If we want a touch button on iPad and the A button on an xbox, we have to make bigger changes to our gamestate class.
  • We can’t write unit tests against our gamestate because we can’t trigger input button presses.

You may be thinking that’s a long list, but I guarantee there are more problems than just those.

Why not just use a Singleton?

The first answer you may come across to some of these problems is the Singleton pattern.
While it’s very popular, simple, and resolves half of our issues, it doesn’t fix the rest.
Because of that, outside the game development world, the singleton pattern is generally considered bad practice and is often referred to as an anti-pattern.

 

Let’s try some separation

Now, let me show you an easy way to resolve all of the problems above.

public class GameStateReadyToStart
{
    public GameStateReadyToStart(IHandleInput inputHandler)
	{
		inputHandler.OnContinue += () =>
		{
			SwitchToNextGameState();
		};
	}

	private void SwitchToNextGameState()
	{
		// Logic to go to next gamestate here
	}
}

Here, you can see we’ve moved input handling out of the “gamestate” object into it’s own “inputHandler” class.  Instead of reading input in an update loop, we simply wait for the InputHandler to tell us when the user is ready to continue.  The gamestate doesn’t care how the user tells us to continue.  All the gamestate cares about is that the user told it to switch to the next state.  It’s now properly separated and doing only what it should do, nothing more.

The “IHandleInput” interface for this example is very simple:

using System;

public interface IHandleInput
{
    Action OnContinue { get; set; }
}

Now, if we want to switch input types across devices, we simply write different implementations of the “IHandleInput interface.
We could for example have implementations like:

  • TouchInputHandler – Continues when the user presses anything bound to “Fire1
  • GUIBasedInputHandler – Continues when the user clicks a GUI button
  • VoiceInputHandler – Continues when the user says a phrase
  • NetworkInputHandler – Continues when the user presses something on another device (think controlling a PC game with a phone)
  • TestInputHandler – Continues via a unit test designed to verify state switching doesn’t break

 

Time to Inject!

Now without going too much deeper into my example, you may be thinking “that’s nice, but now I have to pass in an input handler and manage that”.

This is where dependency injection comes into play.  Instead of creating your handler and passing it into the constructor, what we’ll do is Register the handler(s) we want with our Dependency Injection Container.

To do that, we need to create a new class that derives from the Zenject class “MonoInstaller

using System;
using UnityEngine;
using Zenject;
using Zenject.Commands;

public class TouchGameInstaller : MonoInstaller
{
    public override void InstallBindings()
	{
		Container.Bind<IHandleInput>().ToTransient<TouchInputHandler>();
		Container.Bind<GameStateReadyToStart>().ToTransient<GameStateReadyToStart>();

		Container.Resolve<GameStateReadyToStart>();
	}
}

In the TouchGameInstaller class, we override InstallBindings and register our 2 classes.

Line 13 simply asks the container for an instance of the game state.

This is a very simplified version of the Installer with a single game state, later parts of this series will show how we handle multiple game states.

What we’ve done here though is avoid having to manage the life and dependencies of our “gamestate” class.
The Dependency Injection Container will inspect our classes and realize that the “GameStateReadyToStart” class has a dependency on an “IHandleInput“, because the constructor has it as a parameter.
It will then look at it’s bindings and find that “IHandleInput” is bound to “TouchInputHandler“, so it will instantiate a “TouchInputHandler” and pass it into our “gamestateautomatically.

Now, if we want to switch our implementations on different devices, we simply switch our our “TouchGameInstaller” with a new installer for the device and make no changes to our GameState classes or any existing InputHandler classes.  We no longer risk breaking anything existing when we want to add a new platform.  And we can now hook up our GameState to unit tests by using an Installer that registers a TestInputHandler.

 

You may realize that I haven’t injected any gameobjects yet, and could be wondering how this works with monobehaviors that can’t constructors.

In the next part of this series, I’ll explain how to hook up your gameobjects and monobehaviors with the dependency injection framework and continue the example showing how the entire thing interacts.

 

 

Continue reading >
Share

Editing Unity variables – Encapsulation & [SerializeField]

Editing Unity script variables in the Inspector – The case for Encapsulation & [SerializeField]

If you’ve read many Unity tutorials, you may already know that it’s very easy to edit your script fields in the Unity inspector.

Most Unity tutorials (including on the official page) tell you that if you have a MonoBehaviour attached to a GameObject, any public field can be edited.

While that does technically work, I want to explain why it’s not the best way to setup your scripts, and offer an alternative that I think will help you in the future.

In this article, you’ll learn how to use proper Encapsulation while still taking full advantage of the Unity Inspector.

Take a look at this “Car.cs” script.

 

using UnityEngine;

public class Car : MonoBehaviour
{
    public Tire FrontTires;
	public Tire RearTires;

	public Tire FrontRightTire;
	public Tire FrontLeftTire;
	public Tire RearRightTire;
	public Tire RearLeftTire;

	private void Start()
	{
		// Instantiate Tires
		FrontRightTire = Instantiate(FrontTires);
		FrontLeftTire = Instantiate(FrontTires);

		RearRightTire = Instantiate(RearTires);
		RearLeftTire = Instantiate(RearTires);
	}
}

 

If you look at the Start method, you can tell that the fields “FrontTires” & “RearTires” are referring to prefabs that will be be used to instantiate the 4 tires of the car.

Once we’ve assigned some Tire prefabs, it looks like this in the Inspector.

In play mode, the Start method will instantiate the 4 actual tires on our car and it’ll look like this.


 

Problem #1 – Confusion

The first thing you might realize is that there could be some confusion about which fields to assign the prefab to.
You’ve just seen the code, or in your own projects, perhaps you’ve just written it, and it may seem like a non-issue.

But if your project ever grows, it’s likely others will need to figure out the difference, and to do so, they’ll need to look at the code too.
If your project lasts more than a few days/weeks, you also may forget and have to look back through the code.

Now you could solve this with special naming.  I’ve seen plenty projects where the “Prefab” fields had a prefix or suffix like “Front Tires Prefab”.

That can also work, but then you still have 4 extra fields in there that you have to read every time.  And remember, this is a simple example, your real classes could have dozens of these fields.

Fix #1 – Let’s Use Properties for anything public

To resolve this, let’s change the entries we don’t want to be editable into Properties.

Microsoft recommends you make your fields all private and use properties for anything that is public.  There are plenty of benefits not described in this article, so feel free to read in detail from Microsofts article Fields(C# Programming Guide)

Now let’s change the “Car.cs” script to match this.
using UnityEngine;

public class Car : MonoBehaviour
{
    public Tire FrontTires;
	public Tire RearTires;

	public Tire FrontRightTire { get; set; }
	public Tire FrontLeftTire { get; set; }
	public Tire RearRightTire { get; set; }
	public Tire RearLeftTire { get; set; }

	private void Start()
	{
		// Instantiate Tires
		FrontRightTire = Instantiate(FrontTires);
		FrontLeftTire = Instantiate(FrontTires);

		RearRightTire = Instantiate(RearTires);
		RearLeftTire = Instantiate(RearTires);
	}
}

Here’s what it looks like in the Inspector

With that change, you may be thinking we’ve resolved the issue and everything is good now.
While it’s true that confusion in the editor is all cleared up, we still have one more problem to address.
That problem is lack of Encapsulation.

 


Problem #2 – No Encapsulation

“In general, encapsulation is one of the four fundamentals of OOP (object-oriented programming). Encapsulation refers to the bundling of data with the methods that operate on that data.”

There are countless articles and books available describing the benefits of encapsulation.

The key thing to know is that properly encapsulated classes only expose what’s needed to make them operate properly.

That means we don’t expose every property, field, or method as public.
Instead, we only expose the specific ones we want to be accessed by other classes, and we try to keep them to the bare minimum required.

Why?

We do this so that our classes/objects are easy to interact with.  We want to minimize confusion and eliminate the ability to use the classes in an improper way.

You may be wondering why you should care if things are public.  Afterall, public things are easy to get to, and you know what you want to get to and will ignore the rest.
But remember, current you will not be the only one working on your classes.

If your project lasts beyond a weekend, you need to think about:

  • other people – make it hard for them to misuse your classes.
  • and just as important, there’s future you.

Unless you have a perfect memory, good coding practices will help you in the future when you’re interacting with classes you wrote weeks or months ago.

 


Problem #2 – The Example

Let’s look at this “Wall” script now to get an idea of why proper encapsulation is so important.

using UnityEngine;

public class Wall : MonoBehaviour
{
    public void Update()
	{
		if (Input.GetButtonDown("Fire1"))
			DamageCar(FindObjectOfType<Car>());
	}
	public void DamageCar(Car car)
	{
		car.FrontTires.Tread -= 1;
		car.RearTires.Tread -= 1;
	}
}

The “DamageCar” method is supposed to damage all of the wheels on the car by reducing their Tread value by 1.

Do you see what’s wrong here?

If we look back to the “Car.cs” script, “FrontTires” & “RearTires” are actually the prefabs, not the instantiated tires the car should be using.

In this case, if we execute the method, we’re not only failing to properly damage our tires, we’re actually modifying the prefab values.

This is an easy mistake to make, because our prefab fields that we we shouldn’t be interacting with aren’t properly encapsulated.

Problem #2 – How do we fix it?

If we make the “FrontTires” & “RearTiresprivate, we won’t be able to edit them in the inspector… and we want to edit them in the inspector.

Luckily, Unity developers knew this would be a need and gave us the ability to flag our private fields as editable in the inspector.

[SerializeField]

Adding the [SerializeField] attribute before private fields makes them appear in the Inspector the same way a public field does, but allows us to keep the fields properly encapsulated.

Take a look at the updated car script

using UnityEngine;

public class Car : MonoBehaviour
{
    [SerializeField]
	private Tire _frontTires;
	[SerializeField]
	private Tire _rearTires;

	public Tire FrontRightTire { get; set; }
	public Tire FrontLeftTire { get; set; }
	public Tire RearRightTire { get; set; }
	public Tire RearLeftTire { get; set; }

	private void Start()
	{
		// Instantiate Tires
		FrontRightTire = Instantiate(_frontTires);
		FrontLeftTire = Instantiate(_frontTires);

		RearRightTire = Instantiate(_rearTires);
		RearLeftTire = Instantiate(_rearTires);
	}
}

Here you see we no-longer expose the “FrontTires” and “RearTires” fields outside of our class (by marking them private).

In the inspector, we still see them available to be assigned to.

Now our problems are solved and our class is properly encapsulated!

You may also notice that the casing on them has been changed.  While this is not required to properly encapsulate your objects, it is very common practice in the C# community to denote private fields with camel case prefixed by an underscore.  If you don’t like the underscore, consider at least using camel casing for your private fields and reserve pascal casing for public properties.

Video Version

Project Download

Want the source for this project to try it out yourself? Here it is: https://unity3dcollege.blob.core.windows.net/site/Downloads/Encapsulation%20SerializeField.zip

Continue reading >
Share
Page 4 of 6