Quantcast
Channel: Envato Tuts+ Game Development
Viewing all 728 articles
Browse latest View live

Basic 2D Platformer Physics, Part 8: Slopes

$
0
0
Final product image
What You'll Be Creating

Demo

The demo shows the end result of the slope implementation. Use WASD to move the character. Right mouse button creates a tile. You can use the scroll wheel or the arrow keys to select a tile you want to place. The sliders change the size of the player's character.

The demo has been published under Unity 5.5.2f1, and the source code is also compatible with this version of Unity.

Before We Start...

As was true for the previous parts in the series, we'll be continuing our work where we left off in the last part. Last time we calculated and cached data needed to move the objects out of the slopes collision and changed how the collisions are checked against the tilemap. In this part we'll need the same setup from the end of last part.

You can download the project files from the previous part and write the code along with this tutorial.

In this part we'll be implementing the collision with slopes or other custom tiles, adding one-way slopes, and making it possible for the game object to travel along the slopes smoothly.

Slopes Implementation

Vertical Slope Check

We can finally get to slopes! First off, we'll try to handle when the bottom edge of the object is within a slope tile.

Let's go and take a look at our CollidesWithTileBottom function, particularly the part where we are handling the tiles.

To be able to see whether our object collides with the slope, we first need to get the offsets from the function we created earlier, which does most of our work.

Since we're checking one pixel below our character, we need to adjust the offset.

The condition for the collision is that the freeUp offset is greater or equal to 0, which means that either we move the character up or the character is standing on the slope.

We shouldn't forget about the case when we want the character to stick to the slope, though. This means that even though the character walks off the slope, we want it to behave as if it were on the slope anyway. For this, we need to add a new constant which will contain the value of how steep a slope needs to be in order to be considered a vertical wall instead of a slope.

If the offset is below this constant, it should be possible for the object to smoothly travel along the slope's curve. If it's equal or greater, it should be treated as a wall, and jumping would be needed to climb up.

Now we need to add another condition to our statement. This condition will check whether the character is supposed to be sticking to slopes, whether it was on a slope's last frame, and whether it needs to be pushed down or up by fewer pixels than our cSlopeWallHeight constant.

If the condition is true, we need to save this tile as a potential collidee with the object. We'll still need to iterate through all the other tiles along the X axis. First off, create the variables which will hold the X coordinate and the offset value for the colliding tile.

Now save the values, if the defined condition holds true. If we already found a colliding tile, we need to compare the offsets, and the final colliding tile will be the one for which the character needs to be offset the most.

Finally, after we've iterated through all the tiles and found a tile the object is colliding with, we need to offset the object.

That's pretty much it for the bottom check, so now let's do the top one. This one will be a bit simpler, as we don't even need to handle sticking.

That's it.

Horizontal Slope Check

The horizontal check will be a bit more complicated, as it is here where we'll be handling the most troublesome cases.

Let's start with handling the slopes on the right. There are a couple things that we'll need to be aware of, mostly concerning moving up the slopes. Let's consider the following situations.

Different shaped slopes

We'll need to handle those cases with special care because at some point when we move along the slope we're going to hit the ceiling. To prevent that, we'll need to do some more checks in case the character is moving horizontally.

For the vertical checks, we did move the object up from the tile, but in general we won't be using that functionality there. Since we're always checking a pixel that's just outside the object bounds, we'll never really overlap an obstacle. For the horizontal checks, it's a bit different, because this is the place where we'll be handling moving along the slope, so naturally the height adjustment will mainly take place here.

To make the proper collision response for the cases illustrated above, it'll be easier to check whether we can enter into a space horizontally, and if that's possible then check whether the object doesn't overlap with any solid pixels if it had to be moved vertically due to moving along a slope. If we fail to find the space, we know that it's impossible to move towards the checked direction, and we can set the horizontal wall flag.

Let's move to the CollidesWithTileRight function, to the part where we handle the slopes.

We get the offset in a similar way we get it for the vertical checks, but the offset we care about is the one that's bigger. 

Now, let's see if our character should treat the checked tile as a wall. We do this if either the slope offset is greater or equal to our cSlopeWallHeight constant or to get out of collision we'd need to offset the character up or down while we are already colliding with a tile in the same direction, which means that our object is squeezed between the top and bottom tiles.

If that's not the case and the offset is greater than 0, then we hit a slope. One problem here is that we do not know whether we hit a wall on other tiles that we have yet to check, so for now we'll just save the slope offset and tile collision type in case we need to use them later.

Now, instead of seeing if the slope offset is greater than zero, let's compare it to another tile's slope offset, in case we already found a colliding slope in previous iterations.

Handle the Squeezing Between Tiles

After we finish looping through all the tiles of interest, let's see if we need to move the object. Let's handle the case where the slope offset ended up being non-zero.

We'll have to handle two cases here, and we need to do slightly different things depending whether we need to offset our object up or down.

First off, we need to check whether we can fit into the space after offsetting the object. If that's the case, then we're handling one of the cases illustrated above. Where the character is trying to move right, the offset is positive, but if we offset the object then it will be pushed into the top wall, so instead we'll just mark that it's colliding with the wall on the right side to block the movement in that direction.

If we fit into the space, we'll mark that we collide with the bottom tile and offset the object's position appropriately.

We handle the case in which the object needs to be offset down in a similar manner.

Moving Object in Collision Check

Now this function will offset the object up or down as is necessary if we want to step on the tile to the right, but what if we want to use this function just as a check, and we don't really want to move the character by calling it? To solve this issue, let's add an additional variable named 'move' to mark whether the function can move the object or not.

And move the object only if this new flag is set to true.

Handle Slope Sticking

Now let's handle sticking to slopes. It's pretty straightforward, but we'll need to handle all the corner cases properly, so that the character will stick to the slope without any hiccups along the way.

Before we handle the corner cases, though, we can very easily handle slope sticking within a single tile in the vertical collision check. It will be enough if we add the following condition in the CollidesWithTileBottom function.

This condition makes it so that if the distance between the object's position and the nearest ground is between 0 and the cSlopeWallHeight, then the character will get pushed down too, in addition to the original condition. This unfortunately works only within a single tile; the following illustration pinpoints the problem which we need to solve.

Slope with three squares marked on it

The corner case we are talking about is just this: the character moves down and to the left from tile number one to tile number two. Tile number two is empty, so we need to check the tile below it and see if the offset from the character to tile number 3 is proper to keep walking along the slope there.

Handle the Corner Cases

It's going to be easier to handle these corner cases in the horizontal collision checks, so let's head back to the CollidesWithTileRight function. Let's go to the end of the function and handle the troublesome cases here. 

First off, to handle the slope sticking, the mSticksToSlope flag needs to be set, the object must have been on the ground the previous frame, and the move flag needs to be on.

Now we need to find the tile to which we should stick. Since this function checks the collision on the right edge of the object, we'll be handling the slope sticking for the character's bottom left corner.

Now we need to find a way to compare the height the object currently is on to the one it wants to step onto. If the next height is lower than the current one, but still higher than our cSlopeWallHeight constant, we'll push our object down onto the ground.

Get Slope Height

Let's go back to our Slope class to make a function which will return the height of a slope at a particular position.

The parameters for the function are the x value on the slope and the slope type. If the slope is empty we can immediately return 0, and if it's full then we return the tile size.

We can easily get the height of a slope by using our cached offsets. If the tile is not transformed in any way, we just get an offset for an object that is one pixel wide at the position x, and its height is equal to the tile size.

Let's handle this for different transforms. If a slope is flipped on the X axis, we just need to mirror the x argument.

If the slope is flipped on the Y axis, we need to return the collidingTop instead of collidingBottom offset. Since collidingTop in this case will be negative, we'll also need to flip the sign for it.

Finally, if the tile is rotated by 90 degrees, we'll need to be returning collidingLeft or collidingRight offsets. Aside from that, to get a proper cached offset, we'll need to swap the x and y positions and size.

That's the final function.

Back to Corner Cases

Let's move back to the CollidesWithTileRight function, right where we finished determining the slope types for the tiles the character moves between.

To use the function we just created, we need to determine the position at which we want to get the height of a tile.

Now let's calculate the height between those two points.

If the offset is between 0 and the cSlopeWallHeight constant, then we're going to push the object down, but first we need to check whether we actually can push the object down. This is exactly the same routine we did earlier.

All in all, the function should look like this.

Now we need to do everything analogically for the CollidesWithTileLeft function. The final version of it should take the following form.

That's it. The code should be able to handle all manners of untranslated slopes.

Animation of character moving on slope

Handle Translation Types

Before we start handling translated tiles, let's make a few functions that will return whether a particular TileCollisionType is translated in a particular way. Our collision type enum is structured in this way:

We can use these patterns to tell just by the value of the enum how is a particular collision type translated. Let's start by identifying flip on the X axis.

First, let's get the slope id. We'll do that by calculating the offset from the first defined slope tile to the one we want to identify.

We have eight kinds of translations, so now all we need is get the remainder of dividing the typeId by 8.

So now the translations have an assigned number for them.

The flip on the X axis is present in the types equal to 1, 3, 5, and 7, so if it's equal to one of those then the function should return true, otherwise return false.

In the same way, let's create a function which tells whether a type is flipped on the Y axis.

And finally, if the collision type is rotated.

That's all that we need.

Transform the Offset

Let's go back to the Slopes class and make our GetOffset function support the translated tiles.

As usual, since we don't have cached data for translated slopes, we'll be translating the object's position and size so the result is identical as if the tile has been translated. Let's start with the flip on the X axis. All we need to do here is flip the object along the center of the tile.

Similarly for the flip on the Y axis.

Now in case we flipped the tile on the y axis, the offsets we received are actually swapped. Let's translate them so they actually work the same way as the offsets of the untranslated tile, which means up is up and down is down!

Now let's handle the 90-degree rotation.

Here everything should be rotated by 90 degrees, so instead of basing our posX and sizeX on the left and right edges of the object, we'll be basing them on the top and bottom.

Now we need to do a similar thing to what we did previously if the tile was flipped on the Y axis, but this time we need to do it for both the 90-degree rotation and the Y flip.

This is it. Since our final up and down offsets are adjusted to make sense in the world space, our out of tile bounds adjustments are still working properly.

That's it—now we can use translated slopes as well. 

Animation of character moving on slope

On the animation above, there are 45, 22, 15 and 11-degree slopes. Thanks to the 90-degree rotations, we also can get 79, 75 and 68-degree slopes without defining additional slope tiles. You can also see that the 79-degree slope is too steep to move on smoothly with our value of cSlopeWallHeight.

Handle One-Way Platforms

In all this hassle, we've broken our support for one-way platforms. We need to fix that, and extend the functionality to slopes as well. One-way platforms are as important or often even more important than the solid tiles, so we can't afford to miss them.

Add the One-Way Types

The first thing we need to do is to add new collision types for one-way platforms. We'll add them past the non-one-way collision types and also mark where they start, so later on we have an easy time telling whether a particular collision type is one-way or not.

Now all one-way platforms are between the OneWayStart and OneWayEnd enums, so we can easily create a function which will return this information.

The one-way variants of slopes should point to the same data that the non-one-way platforms do, so no worries of extending memory requirements further here.

Cover the Additional Data

Now let's add variables which will allow us to make an object ignore one-way platforms. One will be an object flag, which will basically be for setting permanent ignoring of one-way platforms—this will be useful for flying monsters and other objects which do not have any need for using the platforms, and another flag to temporarily disable collision with one-way platforms, just for the sake of falling through them.

The first variable will be inside the MovingObject class.

The second one is inside the PositionState structure.

We'll also add another variable here which will hold the Y coordinate of the platform we want to skip.

To make one-way platforms work, we'll simply be ignoring a single horizontal layer of platforms. As we enter another layer, that is our character's Y position has changed in the map coordinates, then we set the character to collide with the one-way platforms again.

Modify the Collision Checks

Let's go to our CollidesWithTileBottom function. First of all, as we iterate through tiles, let's check if it's a one-way platform, and if so, whether we should even consider colliding with this tile or not.

We should collide with one-way platforms only if the distance to the top of the platform is less than the cSlopeWallHeightConstant, so we can actually come on top of it. Let's add this to the condition already laid out, and we also need to assign proper values to state.onOneWay and state.oneWayY.

For the CollidesWithTileTop function, we simply ignore one-way platforms.

For the horizontal collision check, there will be a bit more work. First off, let's create two additional booleans at the beginning, which will serve as information about whether the currently processed tile is one-way, and whether the tile from the previous iteration has been a one-way platform.

Now we're interested in iterating through a one-way platform if we're moving along it. We can't really collide with one-way platforms from right or left, but if the character moves along a slope that's also a one-way platform, then it needs to be handled in the same way that a normal slope would.

Now make sure we can't collide with a slope as if it was a wall.

And if that's not the case and the offset is small enough to climb it, then remember that we're moving along a one-way platform now.

Now what's left here is to make sure that every time we change the position state we also need to update the onOneWay variable.

Jumping Down

We need to stop ignoring the one-way platforms once we change the Y position in the map coordinates. We're going to set up our condition after the movement on the Y axis in the Move function. We need to add it at the end of the second case.

And also at the end of the third case.

That should do it. Now the only thing we need to do for a character to drop from a one-way platform is to set its tmpIgnoresOneWay to true.

Let's see how this looks in action.

New animation of character moving on slope

Summary

Whew, that was a lot of work, but it was worth it. The result is very flexible and robust. We can define any kind of slope thanks to our handling of collision bitmaps, translate the tiles, and turn them into one-way platforms. 

This implementation still isn't optimized, and I'm sure I've missed a lot of opportunities for that handed by our new one-pixel integration method. I'm also pretty sure that a lot of additional collision checks could be skipped, so if you improve this implementation then let me know in the comments section! 

Thanks for sticking with me this far, and I hope this tutorial is of use to you!


Adobe Alternatives: Animation Software

$
0
0

Welcome to the final entry in our series exploring the creative software we have at our disposal outside the familiar world of Adobe. In this article we’ll be going over some awesome alternatives to Animate CC, formerly known as Flash.

Animation in Flash has been used heavily in both game dev and in animated shorts and shows, so we’ll be taking a little look at software you can use for both these purposes. Most of these programs have a strong focus on “skeletal animation”.

For that reason, in case you’re just getting into animation and deciding which tools to use, we’ll start with a quick rundown of skeletal animation to help you better assess the features of each application and which is most suited to you and your projects. Let’s go!

Quick Skeletal Animation Rundown

External Art Creation

The first step in the skeletal animation process is typically using an external application to create artwork comprised of multiple pieces on different layers. For example, you might create a character with separate limbs, torso and head.

When your art is finished you import it in pieces into your animation software and reassemble it. Some tools provide means to automate this import process, saving you the trouble of individual layer exports and manual reassembly.

Bones and Rigging

Once your art is laid out on the canvas correctly you then create a skeleton for your character. Skeletons are comprised of “bones”, and bones get attached to each of the pieces in your character art. This process is typically referred to as “rigging”.

Now when you move a bone the attached images move and rotate along with it, and by manipulating the position and rotation of the bones you can set your character into various poses. Animations are created by putting your character in various poses at different points on the timeline and allowing the software to “tween”, (automatically create frames in between), those poses.

If that doesn’t fully make sense just yet don’t worry, as you’ll see some videos of this process below.

Meshes

Some software takes the skeletal animation process a step further with the addition of “meshes”. Normal bones typically only adjust the position and rotation of attached images. Meshes on the other hand add a series of points over the top of each image, and if any of those points are moved the image’s nearby pixels move too. Through manipulating these points, either manually or via attached bones, you can perform sophisticated bending and warping of shapes, allowing for effects like pseudo 3D rotation or cloth moving in the wind.

Runtimes

Many skeletal animation softwares provide something called “runtimes”, which are libraries of code that allow animation to be rendered at run time in certain game engines or other code based environments. Using runtimes has a couple of benefits.

Firstly, you can dramatically reduce the file size your animations take up because rather than needing an image to represent every frame of a prerendered animation all you need is your artwork in its original pieces and the data on your skeleton and its poses over time.

Secondly, you have the ability to change how the animation works at run time. For example, you might switch out the images associated with your skeleton so you can change your character’s appearance or attachments on the fly. It also allows for smooth transitions between one animation and the next, such as gradually coming to a stop from a running state rather than the body suddenly switching its pose.

That covers the fundamentals of skeletal animation, so now you know what to look for let’s jump into looking at our software!

1. Spine

Spine is a skeletal animation application focused on character animation for game development. It’s one of the most popular tools of its kind, and for good reason. It’s packed with features, has a smooth user experience, and includes a comprehensive list of official and third party runtimes that cover 19 game engines & toolkits and 7 programming languages. Among leading game engines provided for are UnityUnreal Engine, GameMakerConstruct 2 and Phaser.

Spine comes in two flavors: the “Essential” version for $69 and the “Professional” version with more features at $299. However, the inclusions in the “Essential” version are strong and will take you a long way. You’ll be missing out on meshes, free form deformation, clipping, and constraints, but you’ll have everything else.

I find working with Spine to be a very smooth experience and its rigging process is, in my opinion, probably the fastest most efficient among applications of its kind. Once rigged, posing characters is intuitive and straight forward. And from there you can activate the auto key function which allows you to just move the playhead to a particular time, pose your skeleton, and all the appropriate keys will be added for position, rotation and so on. Alternatively you can set keys manually if you’d rather have finer control.

Spine has a skin system that allows you to create animations with one set of attached images, then use the same animations again with a totally different set of images. You can use this to create different versions of the same character or creature, such as switching gender for example, or changing the clothing or weapon images being used. These differing skins then provide either an easy way to render out multiple spritesheets or, if using a runtime, the ability to change these things on the fly

In another feature helpful to game developers, Spine allows you to set bounding boxes that can be used for collision and physics in games. This means you can still have accurate collision even as your character’s shape changes throughout their animation cycle.

With the addition of scripts to Spine, images for animating can have their import automated from GIMP and Inkscape. And if you’re working with both Affinity Designer or Photo you can use its built-in Spine batch export feature. With any of these processes you can start with all your body pieces arranged where they should be, as opposed to manually placing them.

Spine also has the ability to export to video, (AVI and Quicktime), meaning you can use it for all kinds of animation purposes as well as game graphics.

  • Website:http://esotericsoftware.com
  • Platforms: Linux, Mac, Windows
  • Price: $69 for “Essential” version (no meshes, deformation or constraints), $299 for “Professional” version

2. DragonBones

DragonBones a completely free program that is very much like Spine. It doesn’t have full feature parity, but it is quite close and given you don’t pay a penny to use it that makes a pretty compelling case. In Spine you’ll need the “Pro” version to access meshes, IK constraints and free form deformation, but these things are included out of the box in DragonBones.

DragonBones, however, doesn’t have as many runtimes as does Spine. It currently caters for C# (can be used with Unity), JS/TypeScript (use with Pixi, Egret), C++ (use with Cocos2d), ActionScript (use with Flash, Starling), SpriteKit and Java.

One of my favorite features in Spine is the “skins” system, and the same type of functionality is available in DragonBones too, it’s just referred to as an “avatar system” instead.

The fact that DragonBones gives free access to all its features features, including meshes and free form deformation, (the ability to stretch and warp images), means you can create some very cool effects with zero cost software:

Setting up bones is a pretty straight forward experience in DragonBones. It has an auto binding feature where with the “create bone” tool you can just click in the image you want a bone to be bound to then drag out to the desired length. This doesn’t work flawlessly for every image you need to bind, but it certainly gets you part of the way there.

The dev team behind DragonBones is Chinese, and while there are English docs you might just have to read a little carefully as English is the second language of the writers. However I haven’t found any significant difficulty in understanding how things work, which I think is helped along by the fact that tools are placed in the UI in a way that is quite intuitive.

If you’re on Mac or Windows and want to get your skeletal animations rolling with a free application this will be a superb place to start. Note that you will, however, need to login to a free account in order to save your work. Other than that, it’s all open access.

3. Spriter

Spriter is another application in the vein of Spine and DragonBones, being focused on creating animations for games. It’s a little different to the above two options however in that it doesn’t include any meshes, but it does include some interesting features that can help with pixel art assets.

Spriter, like DragonBones, doesn’t have as many runtimes as does Spine. But it does cover the major 2D engines with runtimes for Unity, Construct 2 & Game Maker Studio, and language specific runtimes for C#, C++ and JavaScript.

If you’re a pixel artist looking for a way to speed up animations Spriter is a stand out option for you due to its “Pixel art mode”. With this mode active you can only move sprites in whole pixel increments, preventing any blurred half pixels. Additionally, no sampling happens between pixels as they move, so throughout animations your sprites will always retain crisp, blur free pixels.

There is also a great color palette swapping feature that can be used with art in indexed mode, i.e. restricted to a palette with a fixed number of colors, as is most pixel art. With the help of a runtime this makes it possible to provide players with the ability to change a character’s clothing color, hair color, skin color, eye color and so on.

As with Spine and DragonBones, Spriter also offers the ability to swap out the images associated with your bones when using a runtime. In this case the feature is referred to as “character maps”.

And if using Spriter for game development, you can use it to create collision boxes that can be used in game, again as long as you’re using a runtime.

For Linux users a Spriter build is available, however it’s targeted at Ubuntu 14 and relies on Gstreamer 0.10 which isn’t bundled with the software. On older distros or anything based on Ubuntu 16.04 you should be able to easily install the required Gstreamer version manually. However on later distros you may find only Gstreamer 1.0 or higher is in your repos, making Spriter use problematic. Hopefully the developer will be able to update their Linux version soon, otherwise just be aware you may have to work around this issue.

Spriter has both a free version and a “Pro” version for $69, making it an affordable application among its peers. That said, the free version of Spriter is a solid tool even without the full feature set of the “Pro” version. It allows you to create skeletal animations with basic easing control and basic IK so you can really get a strong feel for the software before deciding whether or not to grab the “Pro” version.

  • Website:https://brashmonkey.com
  • Platforms: Linux (Ubuntu 14), Mac, Windows
  • Price: Free version, and "Pro" version $59.99

4. Creature

In Creature we have another skeletal animation tool focused on game development. However this one is a little different to the above applications because not only does it include meshes in both its versions, in actual fact everything is a mesh.

In Creature as soon as you import an image it becomes a mesh, as opposed to meshes being something optional you can add if you choose. As everything is mesh-based it means all parts of your image can be deformed, and bones can be used to affect any portion of the mesh as well. Through these features you get the ability to create graphics that have a 3D look to them even when done entirely in 2D.

The standout features of Creature are, in my opinion, in its bone motors and force fields. Bone motors give you ways to control the positioning of your bones procedurally, rather than solely through manual posing. And force fields create environmental influences that can further impact how your motor-driven bones move.

For example, to make hair that can blow in the wind you would add bones to the image meshes that make up the hair on a character, then apply a “bend motor” that would apply the physical properties of real hair, e.g. adding the effect of gravity on the hair, determining how stiff the hair is and so on.

Then once you give the hair appropriate physical properties you can add a force field that simulates wind. This will interact with the bend motor on the hair to create the effect of the hair blowing in the breeze. The same process can be used to make clothing, flags and other flexible materials behave with flowing, physical realism.

On top of in-application force fields, another incredibly cool feature Creature has is the ability to add live bend physics into a game. This allows elements of your images to bend in a realistic way according to their movement in game. For example, you might create a fox character whose tail and ears bounce around naturally when they move:

When it comes to runtimes, Creature’s current list includes: C++ (Cocod2d-x, Unreal Engine 4, Godot Engine), Objective-C (Cocod2D), C# (Unity, Monogame), Haxe (Haxe to Flash, HaxeFlixel), Java (libGDX), and JavaScript (Three.js, Babylon.js, Pixi.js, Phaser).

As for what you get in the $99 “Basic” version, you get mesh creation, but not mesh sculpting, optimization and refinement. You get bone motors that can drive bend physics, rope physics, rotation cycles and walking, but you don’t get mesh deformation motors. There’s no path use, but there is spline use. In the “Basic” version you can also swap the sprites associated with meshes, referred to as “skin swapping”.

Right now Creature is available on Mac and Windows, though the lead dev has said Linux support should be coming in the future. Creature has a lot of powerful features that other animation software does not, so it’s definitely an application to try.

5. OpenToonz

OpenToonz is different to the other animation software we’ve covered in that it’s not focused on game dev, but rather on traditional animation for video. Also unlike our other applications OpenToonz is designed for you to be able to draw directly inside the software. OpenToonz is most well known for being the primary software used by beloved animation house Studio Ghibli, as well as being used in Futurama, The Maxx and other popular animated shows and movies.

The animation method in OpenToonz is a different paradigm to the software we’ve talked about so far. There is quite a bit of emphasis on drawing animations frame by frame, though an “auto in-between” tool is available for filling in gaps in your timeline. However, skeletal animation tools are available too, with support for both regular bones as well as meshes.

The included drawing and painting tools are quite robust, with included smoothing / stabilizing and pen pressure support. It also has support for vector based drawing with the ability to modify your art after laying down strokes. Even when working with vectors here the drawing process feels very natural, with no noticeable difference to drawing with raster strokes.

OpenToonz used to be known as Toonz, and since 1993 was a closed source, paid, enterprise level application. Luckily for all of us, it was released as free and open source software in March of 2016. If you’re animating for video it’s a must try.

Wrapping Up

That’s five awesome alternatives to Adobe software in the animation space, each one with a version available for a one time purchase of under $100, (or free). Let’s quickly summary our applications, and crunch down how to decide which fits you best.

Spine right now is the leader in 2D skeletal animation due to its smooth workflow, stack of features, and runtimes for just about everything. The full feature set in the “Pro” version would cost you more than our series price cap, and is more expensive than the highest price point on any of our other software. However the “Essentials” version gives you well enough to get on your way animating. If you’re in game dev there’s a good chance this might be the right animation software for you.

If you’re considering Spine and don’t need Linux support, you should definitely check out DragonBones as part of your decision making process. It’s not quite as smooth to use as Spine but it is very close. It doesn’t have all the features of Spine, but it has several of them. And of course it’s completely free. It does have fewer runtimes available however, so your choice may come down to how important Spine’s extra features are to you, and whether a runtime is available for your chosen engine and / or coding language.

Spriter is has a free version, and also a “Pro” version that’s cheaper than Spine’s “Essential” version, so price-wise it stacks up well against Spine. On the other hand its paid version doesn’t have some of features that DragonBones offers free, which may make it tough to choose over DragonBones. However Spriter does have some great pixel art specific tools that aren’t in other applications and could be very useful for pixel artists. It also has Linux support, which DragonBones does not. So Spriter might be for you if you want those pixel art features, and / or if you’re on Linux and looking for a lower price point than Spine.

Creature is different to the other skeletal animation software we covered in that everything you work with is a mesh, and it has powerful bone motors and force fields. This means you can do all sorts of cool things like warping images to create pseudo 3D, adding realistic physics effects to images so they look like they’re blowing in the wind or being naturally effected by movement. Creature might be for you if you’re on Mac or Windows and the mesh based animation style appeals to you.

OpenToonz is the standout option if the animation you are producing is for rendered video rather than for games. You can paint directly inside the software in either raster or vector format, with stabilizers and pen pressure support. You can’t do much better than the software used by Studio Ghibli, available completely free of charge.

Of course every one of these applications has a massive list of features that is too long to cover completely in this article, so be sure to try each one out for yourself to see everything they have to offer.

That’s a Series Wrap!

And with that, we’re also wrapping up our series exploring the realms beyond our well known Adobe applications, looking to see what other cool software might be out there. Hopefully you’ve found not just some new animation software, but a whole slew of new software to enjoy. Have fun being creative!


How Tuts+ Has Helped People in Their Careers

$
0
0

People use Envato Tuts+ for all kinds of reasons. Sometimes it's just for fun or to pick up some creative skills as a hobby. But many people also use the site to help them in their careers. 

We ran a reader survey earlier this year, and some of the responses were quite inspiring. Here's a look at how some of your fellow learners have used the site to help them make progress in their careers.

Landing Their First Job

Quite a few of our learners are students who use Envato Tuts+ to help them supplement their formal school or university education with some extra practical skills.

Bartłomiej Szubert was one of those people. He started to learn web development from our courses and eBooks while studying, and after a few months he prepared his CV and applied for a web developer position at a company in his city. And he got the job!

Right now I'm a Mid-Level PHP Programmer / Senior Web Developer in another company, while my colleagues from university often haven't even found their first job. And that's all thanks to Envato Tuts+.

For Pouya Rezaei, it was after graduating from university in Economics & Finance that he realised he wanted to work in a different field. So he set out to teach himself everything he needed to know about designing websites. 

Two years later I began freelancing, six years on I am creating websites, design work, PHP, HTML, JavaScript ... Everything I learnt and all the CMS plugins I used for my clients when I first started, it ALL was with the help of you guys. I'm living my life doing what I LOVE. 
Pouya Rezaei
Pouya Rezaei

Humaira Mahinur only started on the site a few months ago, but has already learned a lot and is moving towards a freelance career. 

I am a learner of web design and development, graphic design and other skills ... After completing some projects, by the will of Allah, I will start my career with Envato Studio and some freelance marketplace. 

And Michelle Silva is a graphic design student about to graduate and now working in a printing job to gain some experience. 

This website has definitely helped me improve in areas that I didn't understand or weren't covered in class and need to learn quickly to complete a job. Tuts+ guarantees that the ONE course you watch will help you learn what you need. 
Michelle Silva
Michelle Silva

Finding Better Job Opportunities

Sometimes, people are already on the career ladder, but are not satisfied with the opportunities available to them in their current roles. 

Jenny Yamada, for example, says:

I'm using it to refresh my memory and apply for jobs I wouldn't qualify for otherwise. I was able to build out my website in WordPress from taking Adi's course. 

But you don't always need to move on to move up. Alexander Kozhurkin was already working as a full-time developer, but felt stuck at a junior level. By learning new skills, he was able to start working on more fulfilling projects.

Now I'm working on an enterprise-level business app. I realized that my success depends on my own efforts, and quality education is the key for this. Envato courses let me grow fast, it's like watching an expert coding over his shoulder. 

Making a Career Change

Envato Tuts+ is also helping people retrain so that they can make the career change they've always dreamed of.

Some, like Dave Perlman, are still in the early stages of a career change, but have accumulated skills that are moving them towards a dream job:

I'm closer now than I ever have been to having a career as a web developer and I've only put in about a year learning code.

Others are further along. Treighton Mauldin took a big risk several years ago by quitting his job in the construction industry to pursue a career in web development. 

I had no experience, and no clue where to start. When I found Tuts+ I was able to start learning rapidly, going through the free courses and tutorials, and within a year I had my first full-time job as a developer. Now I am a back end developer and am helping lead a development team of four people. 
Treighton Mauldin
Treighton Mauldin

Another person who switched careers with the help of Tuts+ is Traci Brinling. After being laid off three years ago, she decided to follow her passion for animation and break into a new career. She used our online courses and tutorials to help her make the change.   

I did something right because I am working as an in-house animator and now just trying to build up my freelance client base. 

Meanwhile, Neeru Mokha is using the site to help her get back into work after a career break.

It's really helpful in updating my resume as I took 4 years of break but now I am getting very close to filling my gap. Videos posted are very knowledgeable and very helpful in improving your basic to advanced level skills.

And so is George Millard:

I have got back into software development after a number of years working in a different field. I am using it to get back up to speed and learn the new languages that are now popular.

Being More Effective as a Freelancer

Many freelancers use Envato Tuts+ to brush up on their skills and land better contracts. When Christian Nazha had a client ask for a Laravel site, he tried various other sites to get the information he needed, but none could help him. Some had bad English, poor sound quality, or even skipped the basics. 

Here I found the perfect combination of explanatory and quality videos.

Meanwhile, self-taught web developer Tracey Niblett is using Tuts+ to improve the quality of her work, resulting in big cost savings. 

Tuts+ has really helped to fill in the gaps in my knowledge so that my code has become more efficient and reliable. Reliable code means happy customers and less time supporting and more time developing new stuff so the money I have saved in time supporting has more than covered the cost of my subscription.

Being Their Own Boss

Lisette Marie McGrath has been struggling to set up an online business while grappling with health issues. The online courses and tutorials have helped her to keep her skills updated while working at her own pace. Now her health is improving and she's able to devote more time to her business, using the skills she's acquired.

Envato Tuts+ has kept me going for the last few years, keeping me interested, inspired and focussed on what matters the most to me.

Meanwhile, Martine Kerr says she went from 813 to over 10,000 Instagram followers in just over a year with videos she's created using skills learned on Tuts+, and now she's ready to design and film her own courses.

The skills allowed me to save a huge amount of time in filming and basic editing workflow. I'm now confident enough to create my own online courses.

Doing a Better Job

And finally, what better way to enhance your career than just being better at the day-to-day job you do?

Cassie Porcella got her first job as a corporate web developer/designer five years ago, and she used Tuts+ to help her thrive in the new role. When she started, the company website was very basic, and she used our courses and tutorials to learn the skills she needed to overhaul it.

I quickly started using Tuts+ and it helped me take my coding from basic HTML and CSS to full PHP, MySQL and JavaScript/jQuery. After a full redesign of the site design and architecture to align with our business objectives, I started using Tuts+ to refine the site and add user-friendly features. 

But as we all know, technology is an ever-changing industry, and a couple of years ago, Cassie updated her knowledge with the help of Kezz Bracey's explanations of responsive design

This course helped me to transform our site and its usability and help future-proof the design structure for the multitude of device sizes. Additionally, it really encouraged me to see a female coder getting recognition in a field where us gals are often the minority. Thanks for providing such helpful tutorials that have helped me excel in my job, which benefits my company, our team members and our customers! I look forward to refining my craft and boosting my skills with your help! 
Cassie Porcella
Cassie Porcella

Over to You

How have you used Envato Tuts+ tutorials and courses? Have they helped you in your career? Let us know in the comments below. 

If you haven't tried our full membership yet, why not give it a go? As you can tell from these stories, many people enjoy the kind of career progress that quickly pays for the cost of the subscription. Try our new combined subscription to Envato Tuts+ and Envato Elements. For just $29 a month, you get unlimited video courses and eBooks, plus unlimited downloads from a huge library of professional-quality graphics, photos, web templates, and much more.

Introduction to Axial Coordinates for Hexagonal Tile-Based Games

$
0
0
Final product image
What You'll Be Creating

The basic hexagonal tile-based approach explained in the hexagonal minesweeper tutorial gets the work done but is not very efficient. It uses direct conversion from the two-dimensional array-based level data and the screen coordinates, which makes it unnecessarily complicated to determine tapped tiles. 

Also, the need to use different logic depending on the odd or even row/column of a tile is not convenient. This tutorial series explores the alternative screen coordinate systems which could be used to ease the logic and make things more convenient. I would strongly suggest that you read the hexagonal minesweeper tutorial before moving ahead with this tutorial as that one explains the grid rendering based on a two-dimensional array.

1. Axial Coordinates

The default approach used for screen coordinates in the hexagonal minesweeper tutorial is called the offset coordinate approach. This is because the alternative rows or columns are offset by a value while aligning the hexagonal grid. 

To refresh your memory, please refer to the image below, which shows the horizontal alignment with offset coordinate values displayed.

horizontally aligned hexagonal grid with offset coordinate values

In the image above, a row with the same i value is highlighted in red, and a column with same j value is highlighted in green. To make everything simple, we won't be discussing the odd and even offset variants as both are just different ways to get the same result. 

Let me introduce a better screen coordinate alternative, the axial coordinate. Converting an offset coordinate to an axial variant is very simple. The i value remains the same, but the j value is converted using the formula axialJ = i - floor(j/2). A simple method can be used to convert an offset Phaser.Point to its axial variant, as shown below.

The reverse conversion would be as shown below.

Here the x value is the i value, and y value is the j value for the two-dimensional array. After conversion, the new values would look like the image below.

horizontally aligned hexagonal grid with axial coordinate values

Notice that the green line where the j value remains the same does not zigzag anymore, but rather is now a diagonal to our hexagonal grid.

For the vertically aligned hexagonal grid, the offset coordinates are displayed in the image below.

vertically aligned hexagonal grid with offset coordinate values

The conversion to axial coordinates follows the same equations, with the difference that we keep the j value the same and alter the i value. The method below shows the conversion.

The result is as shown below.

vertically aligned hexagonal grid with axial coordinate values

Before we use the new coordinates to solve problems, let me quickly introduce you to another screen coordinate alternative: cube coordinates.

2. Cube or Cubic Coordinates

Straightening up the zigzag itself has potentially solved most of the inconveniences we had with the offset coordinate system. Cube or cubic coordinates would further assist us in simplifying complicated logic like heuristics or rotating around a hexagonal cell. 

As you may have guessed from the name, the cubic system has three values. The third k or z value is derived from the equation x+y+z=0, where x and y are the axial coordinates. This leads us to this simple method to calculate the z value.

The equation x+y+z=0 is actually a 3D plane which passes through the diagonal of a three-dimensional cube grid. Displaying all three values for the grid will result in the following images for the different hexagonal alignments.

horizontally aligned hexagonal grid with cube coordinate values
vertically aligned hexagonal grid with cube coordinate values

The blue line indicates the tiles where the z value remains the same. 

3. Advantages of the New Coordinate System

You may be wondering how these new coordinate systems help us with hexagonal logic. I will explain a few benefits before we move on to create a hexagonal Tetris using our new knowledge.

Movement

Let's consider the middle tile in the image above, which has cubic coordinate values of 3,6,-9. We have noticed that one coordinate value remains the same for the tiles on the coloured lines. Further, we can see that the remaining coordinates either increase or decrease by 1 while tracing any of the coloured lines. For example, if the x value remains the same and the y value increases by 1 along a direction, the z value decreases by 1 to satisfy our governing equation x+y+z=0. This feature makes controlling movement much easier. We will put this to use in the second part of the series.

Neighbours

By the same logic, it is straightforward to find the neighbours for tile x,y,z. By keeping x the same, we get two diagonal neighbours, x,y-1,z+1 and x,y+1,z-1. By keeping y the same, we get two vertical neighbours, x-1,y,z+1 and x+1,y,z-1. By keeping z the same, we get the remaining two diagonal neighbours, x+1,y-1,z and x-1,y+1,z. The image below illustrates this for a tile at the origin.

the cube coordinates of neighbours of a hexagonal tile at origin

It is so much easier now that we don't need to use different logic based on even or odd rows/columns.

Moving Around a Tile

One interesting thing to notice in the above image is a kind of cyclic symmetry for all the tiles around the red tile. If we take the coordinates of any neighbouring tile, the coordinates of the immediate neighbouring tile can be obtained by cycling the coordinate values either left or right and then multiplying by -1. 

For example, the top neighbour has a value of -1,0,1, which on rotating right once becomes 1,-1,0 and after multiplying by -1 becomes -1,1,0, which is the coordinate of the right neighbour. Rotating left and multiplying by -1 yields 0,-1,1, which is the coordinate of the left neighbour. By repeating this, we can jump between all the neighbouring tiles around the centre tile. This is a very interesting feature which could assist in logic and algorithms. 

Note that this is happening only due to the fact that the middle tile is considered to be at the origin. We could easily make any tile x,y,z to be at the origin by subtracting the values  x, y and z from it and all other tiles.

Heuristics

Calculating efficient heuristics is key when it comes to pathfinding or similar algorithms. Cubic coordinates make it easier to find simple heuristics for hexagonal grids due to the aspects mentioned above. We will discuss this in detail in the second part of this series.

These are some of the advantages of the new coordinate system. We could use a mix of the different coordinate systems in our practical implementations. For example, the two-dimensional array is still the best way to save the level data, the coordinates of which are the offset coordinates. 

Let's try to create a hexagonal version of the famous Tetris game using this new knowledge.

4. Creating a Hexagonal Tetris

We have all played Tetris, and if you are a game developer, you may have created your own version as well. Tetris is one of the easiest tile-based games one can implement, apart from tic tac toe or checkers, using a simple two-dimensional array. Let's first list the features of Tetris.

  • It starts with a blank two-dimensional grid.
  • Different blocks appear at the top and move down one tile at a time until they reach the bottom.
  • Once they reach the bottom, they get cemented there or become non-interactive. Basically, they become part of the grid.
  • While dropping down, the block can be moved sideways, rotated clockwise/anticlockwise, and dropped down.
  • The objective is to fill up all the tiles in any row, upon which the whole row disappears, collapsing the rest of the filled grid onto it.
  • The game ends when there are no more free tiles on top for a new block to enter the grid.

Representing the Different Blocks

As the game has blocks dropping vertically, we will use a vertically aligned hexagonal grid. This means that moving them sideways will make them move in a zigzag manner. A full row in the grid consists of a set of tiles in zigzag order. From this point onwards, you may start referring to the source code provided along with this tutorial. 

The level data is stored in a two-dimensional array named levelData, and the rendering is done using the offset coordinates, as explained in the hexagonal minesweeper tutorial. Please refer to it if you're having difficulty following the code. 

The interactive element in the next section shows the different blocks which we are going to use. There is one more additional block, which consists of three filled tiles aligned vertically like a pillar. BlockData is used to create the different blocks. 

A blank block template is a set of seven tiles consisting of a middle tile surrounded by its six neighbours. For any Tetris block, the middle tile is always filled denoted by a value of 1, whereas an empty tile would be denoted by a value of 0. The different blocks are created by populating the tiles of BlockData as below.

We have a total of seven different blocks.

Rotating the Blocks

Let me show you how the blocks rotate using the interactive element below. Tap and hold to rotate the blocks, and tap x to change the direction of rotation.

To rotate the block, we need to find all the tiles which have a value of 1, set the value to 0, rotate once around the middle tile to find the neighbouring tile, and set its value to 1. To rotate a tile around another tile, we can use the logic explained in the moving around a tile section above. We arrive at the below method for this purpose.

The variable clockWise is used to rotate clockwise or anticlockwise, which is accomplished by moving the array values in opposite directions in arrayRotate.

Moving the Block

We keep track of the i and j offset coordinates for the middle tile of the block using the variables blockMidRowValue and blockMidColumnValue respectively. In order to move the block, we increment or decrement these values. We update the corresponding values in levelData with the block values using the paintBlock method. The updated levelData is used to render the scene after each state change.

Here, currentBlock points to the blockData in the scene. In paintBlock, first we set the levelData value for the middle tile of the block to 1 as it is always 1 for all blocks. The index of the midpoint is blockMidRowValueblockMidColumnValue

Then we move to the levelData index of the tile on top of the middle tile  blockMidRowValue-1,  blockMidColumnValue, and set it to 1 if the block has this tile as 1. Then we rotate clockwise once around the middle tile to get the next tile and repeat the same process. This is done for all the tiles around the middle tile for the block.

Checking Valid Operations

While moving or rotating the block, we need to check if that is a valid operation. For example, we cannot move or rotate the block if the tiles it needs to occupy are already occupied. Also, we cannot move the block outside our two-dimensional grid. We also need to check if the block can drop any further, which would determine if we need to cement the block or not. 

For all of these, I use a method canMove(i,j), which returns a boolean indicating if placing the block at i,j is a valid move. For every operation, before actually changing the levelData values, we check if the new position for the block is a valid position using this method.

The process here is the same as paintBlock, but instead of altering any values, this just returns a boolean indicating a valid move. Although I am using the rotation around a middle tile logic to find the neighbours, the easier and quite efficient alternative is to use the direct coordinate values of the neighbours, which can be easily determined from the middle tile coordinates.

Rendering the Game

The game level is visually represented by a RenderTexture named gameScene. In the array levelData, an unoccupied tile would have a value of 0, and an occupied tile would have a value of 2 or higher. 

A cemented block is denoted by a value of 2, and a value of 5 denotes a tile which needs to be removed as it is part of a completed row. A value of 1 means that the tile is part of the block. After each game state change, we render the level using the information in levelData, as shown below.

Hence a value of 0 is rendered without any tint, a value of 1 is rendered with red tint, a value of 2 is rendered with blue tint, and a value of 5 is rendered with green tint.

5. The Completed Game

Putting everything together, we get the completed hexagonal Tetris game. Please go through the source code to understand the complete implementation. You will notice that we are using both offset coordinates and cubic coordinates for different purposes. For example, to find if a row is completed, we make use of offset coordinates and check the levelData rows.

Conclusion

This concludes the first part of the series. We have successfully created a hexagonal Tetris game using a combination of offset coordinates, axial coordinates, and cube coordinates. 

In the concluding part of the series, we'll learn about character movement using the new coordinates on a horizontally aligned hexagonal grid.

How to Model a Low Poly Wolf in Cinema 4D: Part 1

$
0
0
Final product image
What You'll Be Creating

Follow this tutorial step-by-step to create a low poly wolf model that you can use in video games, graphic design and illustration projects whilst learning Cinema 4D quickly. 

Some of the skills you'll learn in this tutorial include creating basic 3D modelling, importing reference images, adding lighting to the scene and basic rendering techniques.

In this, the first part of the two-part tutorial, I'll show you how to:

  • How to Import Reference Images
  • How to Prepare for Modelling
  • How to Model the Wolf Body
  • How to Model the Wolf Head

1. How to Import Reference Images

Step 1

Open Follow this tutorial step-by-step to create a low poly wolf model that you can use in video games, graphic design and illustration projects whilst learning Cinema 4D quickly.  and use the middle mouse button to click anywhere on the viewport. This will display all four views. From there, use the middle mouse button to select the Right view.

Multiple viewport by clicking on the middle mouse button
Multiple viewport by clicking on the middle mouse button

Step 2

In the Attributes tab select Mode > View Settings.

Attributes tab select Mode  View Settings
Attributes tab select Mode View Settings

Step 3

In Viewport [Right] select the Back button and click on the button next to Image. 

Selecting reference image
Selecting reference image

Step 4

Select your reference image from the finder and open it. In this tutorial we will use the side profile of a wolf to help us. 

Reference image shown in the background
Reference image shown in the background

2. How to Prepare for Modelling

Step 1

Increase the transparency of your reference image by entering a percentage or using the bar next to the transparency option. For this tutorial we have set the percentage to 70%.


Setting transparency to 70
Setting transparency to 70

Step 2

To create the model of our wolf we need to create a Loft. Select Subdivision Surface > Loft.

Selecting Loft
Selecting Loft

Step 3

Delete the Phong Tag from your Loft. This will remove any smoothing from your model and will ensure that it maintains the Low Poly look.

Removing the Phong Tag
Removing the Phong Tag

Step 4

Select Pen > n-Side. This will create the polygons that we will use to model the Low Poly Wolf.

Selecting n-Side
Selecting n-Side

Step 5

Move the n-Side below the Loft. This will enable the option to edit the polygon.

Moving n-Side below Loft
Moving n-Side below Loft

Step 6

Use the Move Tool to position the n-Side so that it is in line with the left side of the wolf in your reference image. 

Positioning n-Side to fir the reference image
Positioning n-Side to fir the reference image

3. How to Model the Wolf Body

Step 1

Make sure that you have n-Side selected on your side panel.

n-Side is selected
n-Side is selected

Step 2

Use the Move Tool and hold the Control button on your keyboard then hover over the arrow. The mouse pointer should change to indicate that you can duplicate the polygons. From there, simply click and drag to create polygons for your wolf.

Duplicating polygons
Duplicating polygons

Step 3

Use the Scale Tool to scale the shape of your polygon down or up so that it matches your reference image as it reaches specific points in the body. For example, scale the polygon down as your reach the start of the hip as shown in the image below.

Using the scale tool
Using the scale tool

Step 4

Use the Rotate Tool to change the direction of your polygon so that it follows the shape of the wolfs body according to the reference image.

Using the Rotate Tool
Using the Rotate Tool

Step 5

Continue to use a combination of the Move Tool, Rotate Tool and the Scale Tool, until you have completely mapped out the body of your wolf.

Modelling the shape of the body using the image reference
Modelling the shape of the body using the image reference

Step 6

Return to perspective mode by using the middle mouse button and selecting the perspective view. 

Body of the Wolf in perspective view
Body of the Wolf in perspective view

Step 7

Make sure that Loft is selected. This will enable new options in the bottom right corner.

Loft selected
Loft selected

Step 8

Tick the box for Linear Interpolation. Now adjust the three top options(Mesh Subdivision U, Mesh Subdivision V and Isoparm Subdivision U) in order to create a low poly look that is to your liking.

Editing the Loft properties
Editing the Loft properties

Step 9

Repeat the steps above to create other parts of the body like the tail.

Adding the tail to the body of the Wolf
Adding the tail to the body of the Wolf

4. How to Model the Wolf Head

Step 1

Repeat the steps above, using a combination of the Move Tool, Rotate Tool and the Scale Tool, to create the head of the wolf. 

Modelling the Wolfs head
Modelling the Wolfs head

Step 2

Create a Pyramid by selecting Cube > Pyramid. This will be used to create the ears of the wolf.

Selecting Pyramid tool from menu
Selecting Pyramid tool from menu

Step 3

Use the Scale Tool to scale down your pyramid to a size which is suitable for the wolf's ear.

Scaling down the pyramid
Scaling down the pyramid

Step 4

Use the Move Tool and the Rotation Tool to place the pyramid on top of the Wolf's head.

Adding the ear to the head
Adding the ear to the head

Step 5

Return to Perspective View (using the middle mouse button) and move the pyramid to the correct part of the Wolf's head. You can use the Move Tool and the Rotation Tool to do this. Make sure that the base of your pyramid is embedded inside the Wolf's head.

Moving the ear to the correct position on the head
Moving the ear to the correct position on the head

Step 6

Once you are happy with the position of the ear, click the Make Editable button on the top left corner of the viewport (make sure that the pyramid is selected).

Rotating the ear
Rotating the ear

Step 7

Click on the Points button. This will enable you to edit and move the vertices of an object you have selected (in this case the Pyramid).

Selecting the points button
Selecting the points button

Step 8

Select the top point of the Pyramid and use the Move Tool, to extend the height of the ear.

Editing the points of the ear
Editing the points of the ear

Step 9

Click on the Polygons button. This will enable you to edit and move the polygons of an object you have selected (in this case the Pyramid).

Selecting the polygons button
Selecting the polygons button

Step 10

Use the Move Tool and push the front face back so that the ear appears thinner. You can also use the Rotation Tool to rotate and edit the shape of the ear. Once you finished editing the ear make sure you select Model Mode again (located below the Make Editable button).

Editing the polygons of the ear
Editing the polygons of the ear

Step 11

Make sure that you have the Pyramid selected. At the top of the screen, hover over the Array button and click and hold to expand the menu. Select the Symmetry button. Then  move the Pyramid inside Symmetry.

Adding a symmetry modifier to the ear
Adding a symmetry modifier to the ear

Step 12

Use the Move Tool to make sure the ears appear in the correct place.

Moving the ears to the right place
Moving the ears to the right place

Coming Next...

In the second part of the the tutorial series, I'll show you how to:

  • How to Model the Neck
  • How to Model the Legs
  • How to Model the Paws
  • How to Prepare for Rendering
  • How to Create a Background
  • How to Add Lighting and Render the Scene


Hexagonal Character Movement Using Axial Coordinates

$
0
0
Final product image
What You'll Be Creating

In the first part of the series, we explored the different coordinate systems for hexagonal tile-based games with the help of a hexagonal Tetris game. One thing you may have noticed is that we are still relying on the offset coordinates for drawing the level onto the screen using the levelData array. 

You may also be curious to know how we could determine the axial coordinates of a hexagonal tile from the pixel coordinates on the screen. The method used in the hexagonal minesweeper tutorial relies on the offset coordinates and is not a simple solution. Once we figure this out, we will proceed to create solutions for hexagonal character movement and pathfinding.

1. Converting Coordinates Between Pixel and Axial

This will involve some math. We will be using the horizontal layout for the entire tutorial. Let's start by finding a very helpful relationship between the regular hexagon's width and height. Please refer to the image below.

Hexagonal tile its angles  lengths are displayed

Consider the blue regular hexagon on the left of the image. We already know that all the sides are of equal length. All the interior angles are 120 degrees each. Connecting each corner to the centre of the hexagon will yield six triangles, one of which is shown using red lines. This triangle has all the internal angles equal to 60 degrees. 

As the red line splits the two corner angles in the middle, we get 120/2=60. The third angle is 180-(60+60)=60 as the sum of all angles within the triangle should be 180 degrees. Thus essentially the triangle is an equilateral triangle, which further means that each side of the triangle has the same length. So in the blue hexagon the two red lines, the green line and each blue line segment are of the same length. From the image, it is clear that the green line is hexTileHeight/2.

Proceeding to the hexagon on the right, we can see that as the side length is equal to hexTileHeight/2, the height of the top triangular portion should be hexTileHeight/4 and the height of the bottom triangular portion should be hexTileHeight/4, which totals to the full height of the hexagon, hexTileHeight

Now consider the small right-angled triangle in the top left with one green and one blue angle. The blue angle is 60 degrees as it is the half of the corner angle, which in turn means that the green angle is 30 degrees (180-(60+90)). Using this information, we arrive at a relationship between the height and width of the regular hexagon.

Converting Axial to Pixel Coordinates

Before we approach the conversion, let's revisit the image of the horizontal hexagonal layout where we have highlighted the row and column in which one of the coordinates remains the same.

Horizontal hexagonal layout with rows and columns highlighted where coordinates remain same

Considering the screen y value, we can see that each row has a y offset of 3*hexTileHeight/4, while going down on the green line, the only value that changes is i. Hence, we can conclude that the y pixel value only depends on the axial i coordinate.

Where s is the side length, which was found to be hexTileHeight/2.

The screen x value is a bit more complicated than this. When considering the tiles within a single row, each tile has an x offset of hexTileWidth, which clearly depends only on the axial j coordinate. But each alternative row has an additional offset of hexTileWidth/2 depending on the axial i coordinate.

Again considering the green line, if we imagine it was a square grid then the line would have been vertical, satisfying the equation x=j*hexTileWidth. As the only coordinate that changes along the green line is i, the offset will depend on it. This leads us to the following equation.

So here we have them: the equations to convert axial coordinates to screen coordinates. The corresponding conversion function is as below.

The revised code for drawing the hexagonal grid is as follows.

Converting Pixel to Axial Coordinates

Reversing those equations with the simple substitution of one variable will lead us to the screen to axial conversion equations.

Although the required axial coordinates are integers, the equations will result in floating point numbers. So we will need to round them off and apply some corrections, relying on our main equation x+y+z=0. The conversion function is as below.

Check out the interactive element, which uses these methods to display tiles and detect taps.

2. Character Movement

The core concept of character movement in any grid is similar. We poll for user input, determine the direction, find the resulting position, check if the resulting position falls inside a wall in the grid, else move the character to that position. You may refer to my isometric character movement tutorial to see this in action with respect to isometric coordinate conversion. 

The only things that are different here are the coordinate conversion and the directions of motion. For a horizontally aligned hexagonal grid, there are six available directions for motion. We could use the keyboard keys A, W, E, D, X, and Z for controlling each direction. The default keyboard layout matches the directions perfectly, and the related functions are as below.

The diagonal directions of motion make an angle of 60 degrees with the horizontal direction. So we can directly calculate the new position using trigonometry by using Cos 60 and Sine 60. From this movementVector, we find out the new resulting position and check if it falls inside a wall in the grid as below.

We add the movementVector to the hero position vector to get the new position for the hero sprite's centre. Then we find the position of the four corners of the hero sprite and check if those are colliding. If there are no collisions, then we set the new position to the hero sprite. Let's see that in action.

Usually, this kind of free-flowing motion is not allowed in a grid-based game. Typically, characters move from tile to tile, that is, tile centre to tile centre, based on commands or tap. I trust that you can figure the solution out by yourself.

3. Pathfinding

So here we are on the topic of pathfinding, a very scary topic for some. In my previous tutorials I never tried to create new pathfinding solutions but always preferred to use readily available solutions which are battle tested. 

This time, I am making an exception and will be reinventing the wheel, mainly because there are various game mechanics possible and no single solution would benefit all. So it is handy to know how the whole thing is done in order to churn out your own custom solutions for your game mechanic. 

The most basic algorithm that is used for pathfinding in grids is Dijkstra's Algorithm. We start at the first node and calculate the costs involved in moving to all the possible neighbour nodes. We close the first node and move to the neighbour node with the lowest cost involved. This is repeated for all the non-closed nodes till we reach the destination. A variant of this is the A* algorithm, where we also use a heuristic in addition to the cost. 

A heuristic is used to calculate the approximate distance from the current node to the destination node. As we do not really know the path, this distance calculation is always an approximation. So a better heuristic will always yield a better path. Now, that being said, the best solution need not be the one which yields the best path as we need to consider the resource usage and performance of the algorithm as well, when all the calculations need to be done in real time or once per update loop. 

The easiest and simplest heuristic is the Manhattan heuristic or Manhattan distance. In a 2D grid, this is actually the distance between the start node and end node as the crow flies, or the number of blocks we need to walk.

Hexagonal Manhattan Variant

For our hexagonal grid, we need to find a variant for the Manhattan heuristic to approximate the distance. As we are walking on the hexagonal tiles, the idea is to find the number of tiles we need to walk over to reach the destination. Let me show you the solution first. Please move the mouse over the interactive element below to see how far away the other tiles are from the tile under the mouse.

In the example above, we find the tile under the mouse and find the distance of all other tiles from it. The logic is to find the difference of i and j axial coordinates of both tiles first, say di and dj. Find the absolute values of these differences, absi and absj, as distances are always positive. 

We notice that when both di and dj are positive and when both di and dj are negative, the distance is absi+absj. When di and dj are of opposite signs, the distance is the bigger value among absi and absj. This leads to the heuristic calculation function getHeuristic as below.

One thing to notice is that we are not considering if the path is really walkable or not; we just assume that it is walkable and set the distance value. 

Finding the Hexagonal Path

Let's proceed with pathfinding for our hexagonal grid with the newly found heuristic method. As we will be using recursion, it will be easier to understand once we breakdown the core logic of our approach. Each hexagonal tile will have a heuristic distance and a cost value associated with it.

  • We have a recursive function, say findPath(tile), which takes in one hexagonal tile, which is the current tile. Initially this will be the starting tile.
  • If the tile is equal to the end tile, the recursion ends and we have found the path. Else we proceed with the calculation.
  • We find all the walkable neighbours of the tile. We will loop through all the neighbour tiles and apply further logic to each of them unless they are closed.
  • If a neighbour is not previously visited and not closed, we find the distance of the neighbour tile to the end tile using our heuristic. We set the neighbour tile's cost to current tile's cost + 10. We set the neighbour tile as visited. We set the neighbour tile's previous tile as the current tile. We do this for a previously visited neighbour as well if the current tile's cost + 10 is less than that neighbour's cost.
  • We calculate the total cost as the sum of the neighbour tile's cost value and the heuristic distance value. Among all the neighbours, we select the neighbour which gives the lowest total cost and call findPath on that neighbour tile.
  • We set the current tile to closed so that it won't be considered anymore.
  • In some cases, we'll fail to find any tile which satisfies the conditions, and then we close the current tile, open the previous tile, and redo.

There is an obvious failure condition in the logic when more than one tile satisfies the conditions. A better algorithm will find all the different paths and select the one with the shortest length, but we won't be doing that here. Check the pathfinding in action below.

For this example, I am calculating neighbours differently than in the Tetris example. When using axial coordinates, the neighbour tiles have coordinates which are higher or lower by a value of 1.

The findPath recursive function is as below.

It may require further and multiple reading to properly understand what is going on, but believe me, it is worth the effort. This is only a very basic solution and could be improved a lot. For moving the character along the calculated path, you can refer to my isometric path following tutorial

Marking the path is done using another simple recursive function, paintPath(tile), which is first called with the end tile. We just mark the previousNode of the tile if present.

Conclusion

With the help of all the three hexagonal tutorials I have shared, you should be able to get started with your next awesome hexagonal tile-based game. 

Please be advised that there are other approaches as well, and there's a lot of further reading out there if you are up for it. Please do let me know through the comments if you need anything more to be explored in relation to hexagonal tile-based games. 

Expired: Join Envato Elements for Just $19!

$
0
0

This Promotion is Now Expired

Unfortunately this promotion has now come to an end. You can read about the other promotions that are happening for Envato's birthday though. There's still lots to explore!

What is Envato Elements?

To celebrate Envato's 11th birthday, we're excited to share a one-day promotion for Envato Elements. Usually $29, for one day only you can lock in a lifetime price of just $19 per month!

Envato Elements provides inspiring and ready-to-use photos, templates, fonts, assets, icons, and much more. For a single monthly fee, you get unlimited downloads to use in your projects and design work.

Now with over 33,000 beautiful design templates and assets (and over 300,000 photos), it's the only design subscription you'll ever need.

Not only that, Envato Elements now includes access to every Tuts+ course and eBook. That's over 1,000 courses on web design, code, and graphic design, as well as the entire A Book Apart and Smashing Magazine eBook libraries!

Head over to Envato Elements any time today, and you can take advantage of a one-off discount, for the lifetime of your membership. Join today for $19 and you lock that price in for all future months.

Act fast, though. The promotion ends tomorrow, at 12pm Wednesday 23rd August, AEST (Australian time). You can see the end time of the promotion in other time zones, to make sure you don't miss out!

What Else is Happening?

There's lots more planned for Envato's birthday over the coming weeks. Keep an eye out for another post this week with all the details, but you can visit Envato's birthday landing page to find out more about:

  • Special free files from our marketplaces
  • 50% discounts on over 300 Envato Market files
  • A 20% discount on Envato Studio services

Thanks for celebrating our birthday with us, and we hope you'll enjoy this fantastic, one-off Envato Elements discount!

Welcome to a Week of Discounts in Envato's Birthday Sale!

$
0
0

It's Envato's 11th birthday this week, but it's OK—you don't have to buy us a gift. In fact, we're celebrating by giving you some gifts. Read on for news of some huge discounts and freebies available this week only. Or visit Envato's birthday sale page to access the discounts right away.

Envato birthday sale

8 Free Items on Envato Elements

The premium creative assets on Envato Elements are usually available via monthly subscription only, but this week you can download eight items absolutely free. 

Among the items in this curated bundle of freebies are an elegant travel magazine template, a set of social media banners for a blog, a corporate presentation template, and more. Check out the full set of Envato Elements freebies, and download them to use in any personal or commercial project.

Envato Elements birthday sale

50% Off Popular Envato Market Items

Over on Envato Market, some of the popular items are half price this week. The 50% discount applies to a collection of top themes, plugins, audio, video and graphic assets from the most popular categories.

As long as you buy before 12 pm on 29 August AEST (Australian Eastern Standard Time), you can take advantage of these special sale prices. Find out more about the Envato Market 50% birthday sale.

Envato Market discounts

20% Off Everything at Envato Studio

Do you need to get some custom design work done by skilled freelancers? How about having an app developed, or getting video and audio services? 

You can have all of that done by expert providers on Envato Studio, and this week it's even cheaper. Between now and 29 August, you can get 20% off any Envato Studio service. 

View more details of the 20% sale at Envato Studio.

Envato Studio birthday sale

Thank You!

Envato has come a long way in the 11 years since it first opened its doors back in 2006, and the community has been a big part of that. That's why the company's core value is:

"When the Community Succeeds, We Succeed."

Whether you're an Envato Elements subscriber, a buyer on Envato Market and Envato Studio, an contributor to our libraries of content, or a reader here on Envato Tuts+, you're a part of that community. So thank you for helping us reach the ripe old age of 11. Don't forget to lock in your birthday discounts before they expire!


New eBooks from A Book Apart, Smashing Magazine & more!

$
0
0

If you're a graphic or web designer with a thirst for knowledge, you're in luck. We've just partnered with A Book Apart and Smashing Magazine to bring you dozens of eBooks from some of the leading names in the industry, like CodePen co-founder Chris Coyier and typography guru Jason Santa Maria.

Purchasing or subscribing to all of these would normally put you back upwards of USD $320—but with an unlimited Envato Elements subscription, all top titles and latest releases are included.

That's on top of 30,000+ ready-to-use graphic assets, 280,000+ stock photos, and 1,000+ video courses!

Explore the full library or find popular picks below.

New eBooks

A Book Apart

Smashing Magazine

More

Start Reading With a Combined Subscription

This is just a small selection of the dozens of books available. You can start reading straight away with a subscription to Envato Elements. For a single low monthly fee, you get access not only to these eBooks, but also to our growing library of over 1,000 video courses on Envato Tuts+.

Plus you now get unlimited downloads from the huge Envato Elements library of 280,000+ photos and 30,000+ design assets and templates. Create with unique fonts, photos, graphics and templates, and deliver better projects faster.

10 Days of Freebies From Envato Tuts+

$
0
0

What better way to celebrate ten years of Envato Tuts+, than with a fantastic selection of freebies and resources for our community? Join us as we take a look at how Tuts+ has changed over the last ten years, and share a selection of free courses, templates, eBooks, graphics, and lots more.

Want to jump straight to the freebies? Just click the banner to join our newsletter and get the first item in your inbox!

10 Years of Tuts+

Not many of you will remember when Tuts+ used to look like this! But at its core, Tuts+ remains focused on exactly the same thing we started out doing. We're teaching technical and creative skills, helping people grow in their careers. In the past decade, we've:

  • Published over 24,000 tutorials (and 15,000 translations)
  • Published over 1,000 video courses
  • Grown from one topic (Photoshop) to nine topics
  • Re-built our entire platform three times (with countless re-designs!)
  • Grown our team from one, to fourteen, fantastic editors and experts
  • Worked with over 1,800 talented instructors and translators

10 Days of Freebies

This month, we're doing something a bit special to celebrate the ten year anniversary of Envato Tuts+. We'll have a selection of "10" themed content in Design & Illustration, as well as a fantastic promotion featuring ten days of freebies.

What will we be giving away? We don't want to spoil the surprise, but you can look forward to a selection of:

  • Free courses and videos
  • Graphics, backgrounds, icons, and brushes
  • Presentation templates
  • Exclusive eBooks
  • And much more!

Just join our Tuts+ newsletter to get started. You'll receive a daily email for the next ten days, with a different freebie to download (or watch) every day. The first one will land in your inbox straight away! Here's a sneak peek at some of what you can expect:

Thank You!

We've had an incredible ten years creating tutorials, courses, eBooks, quizzes, learning guides, and so much more. We know it's had a wonderful impact on many of you, changed lives, and helped further countless careers.

Thank you for reading Tuts+, subscribing to watch our courses, commenting, sharing, and being part of Envato's incredible community of creators.

Here's to the next ten years!

Creating a Simple 3D Endless Runner Game Using Three.js

$
0
0
Final product image
What You'll Be Creating

The web platform has had a tremendous growth in recent times with the help of HTML5, WebGL, and the increased power of the current generation of devices. Now mobile devices and browsers are capable of delivering high-performing content both in 2D and 3D. The familiarity of JavaScript (JS) as a scripting language has also been a driving factor, after the demise of the Flash web platform. 

Most web developers are well aware of how complicated the JS ecosystem is with all the various frameworks and standards available, which could sometimes be overwhelming to a new developer. But when it comes to 3D, the choices are straightforward, thanks to Mr.Doob. His Three.js is currently the best option out there to create high-performing 3D WebGL content. Another powerful alternative is Babylon.js, which could also be used to make 3D games.

In this tutorial, you'll learn to create a simple endless runner style native web 3D game using the powerful Three.js framework. You will use the arrow keys to control a snowball rolling down a mountainside in order to dodge the trees in your path. There is no art involved, and all visuals are created in code.

1. Basic 3D Scene

Envato Tuts+ already has a few tutorials which could get you started with Three.js. Here are some of them to get you started.

Let's create a basic 3D scene first, as shown here where there is a rotating cube. You can use mouse drag to orbit around the cube.

Any graphic displayed on a two-dimensional screen is practically 2D in nature, with a few important elements which provide the 3D illusion: the lighting, the shading, the shadows, and the 3D to 2D projection magic which happens via the camera. In the above scene, we enable effective lighting using these lines of code.

The renderer needs to have shadowMap enabled, the scene needs to have a light with castShadow enabled, and all 3D objects need the castShadow and receiveShadow properties set appropriately. For proper shading to happen, we should also use the MeshStandardMaterial or a more feature-rich material for our 3D objects. The camera is controlled using the nifty OrbitControls script. I would recommend playing around with the basic 3D scene by adding more primitive shapes or playing with the lighting, etc., before proceeding with the tutorial.

2. The Endless Runner Concept

There are many types of endless runner games, and ours is an 'endless roller'. We will create a game where a snowball is rolling down an endless mountainside where we use the arrow keys to dodge the incoming trees. One interesting thing is that this simple game will not involve any art assets, as all the components would be created by code. Here is the full game to play around.

3. Components of the Game

The main components or elements of the game are: 

  • the rolling snowball
  • the random trees
  • the scrolling ground
  • the distance fog
  • the collision effect

We will explore each of these one by one in the following section.

The Fog

The fog is a property of the 3D scene in Three. It is always a handy trick to use in order to simulate depth or show a horizon. The colour of the fog is important for the illusion to work properly and depends on the colour of the scene and lighting. As you can see in the code below, we also set the renderer's clearColor value to be close to the colour of the fog.

In order to match the ambience, we are also using similar colour values to the lights used in the scene. Every ambient colour is a different shade of white which gels together to create the necessary effect.

The Snowball

Our snowball is a DodecahedronGeometry three primitive shape created as shown below.

For all 3D elements in this game, we are using THREE.FlatShading to get the desired low-poly look.

The Scrolling Mountain

The scrolling ground named rollingGroundSphere is a big SphereGeometry primitive, and we rotate it on the x axis to create the moving ground illusion. The snowball does not really roll over anything; we are just creating the illusion by keeping the ground sphere rolling while keeping the snowball stationary. 

A normal sphere primitive will look very smooth and therefore won't provide the necessary ruggedness needed for the mountain slope. So we do some vertex manipulations to change the smooth sphere surface into a rugged terrain. Here is the corresponding code followed by an explanation.

We are creating a sphere primitive with 40 horizontal segments (sides) and 40 vertical segments (tiers). Each vertex of a three geometry can be accessed via the vertices array property. We loop through all the tiers between the extreme top and extreme bottom vertices to do our vertex manipulations. Each tier of the sphere geometry contains exactly sides number of vertices, which forms a closed ring around the sphere. 

The first step is to rotate every odd ring of vertices to break the uniformity of the surface contours. We move every vertex in the ring by a random fraction between 0.25 and 0.75 of the distance to the next vertex. As a result of this, the vertical vertices of the sphere are not aligned in a straight line anymore, and we get a nice zigzag contour. 

As the second step, we provide each vertex with a random height adjustment aligned with the normal at the vertex, irrespective of the tier to which it belongs. This results in an uneven and rugged surface. I hope the vector mathematics used here are straightforward once you consider that the centre of the sphere is considered the origin (0,0).

The Trees

The trees appear outside our rolling track to add depth to the world, and inside as obstacles. Creating the tree is a bit more complicated than the rugged ground but follows the same logic. We use a ConeGeometry primitive to create the top green part of the tree and a CylinderGeometry to create the bottom trunk part. 

For the top part, we loop through each tier of vertices and expand the ring of vertices followed by shrinking down the next ring. The following code shows the blowUpTree method used to expand the alternative ring of vertices outwards and the tightenTree method used to shrink down the next ring of vertices.

The blowUpTree method pushes out every alternative vertex in a ring of vertices while keeping the other vertices in the ring at a lesser height. This creates the pointy branches on the tree. If we use the odd vertices in one tier then we use the even vertices in the next tier so that the uniformity is broken. Once the complete tree is formed, we give it a random rotation on the y axis to make it look slightly different.

The Explosion Effect

The block pixel explosion effect is not the most elegant one we could use, but it certainly performs well. This particular particle effect is actually a 3D geometry which is manipulated to look like an effect using the THREE.Points class. 

The addExplosion method adds 20 vertices to the vertices array of the particleGeometry. The explode method is called when we need the effect to run, which randomly positions each vertex of the geometry. The doExplosionLogic gets called in the update method if the particle object is visible, where we move each vertex outwards. Each vertex in a points object gets rendered as a square block.

4. The Gameplay

Now that we know how to create each of the items needed for the game, let's get into the gameplay. The main gameplay elements are:

  • the game loop
  • the placement of the trees
  • the user interaction
  • the collision detection

Let's analyse those in detail.

The Game Loop

All the core game mechanic happens in the game loop, which in our case is the update method. We call it for the first time from the init method, which gets called on window load. After this, it hooks onto the document render loop using the requestAnimationFrame method so that it gets called repeatedly. 

In update, we call the render method, which uses the renderer to draw the scene. We call the doTreeLogic method, which checks for collision and also removes the trees once they have gone out of view. 

The snowball and the ground spheres get rotated while we also add a random bouncing logic to the snowball. New trees are placed in the path by calling addPathTree after a pre-defined time has elapsed. Time is tracked using a THREE.Clock object. We also update the score unless a collision has occurred.

Placement of the Trees

One set of trees is placed outside the rolling track to create the world using the addWorldTrees method. All trees are added as a child of the rollingGroundSphere so that they also move when we rotate the sphere. 

To plant world trees, we call the addTree method by passing values around the circumference of our ground sphere. The sphericalHelper utility helps us find the position on the surface of a sphere.

To plant trees on the path, we will make use of a pool of trees which are created on start using the createTreesPool method. We also have pre-defined angle values for each path on the sphere stored in the pathAngleValues array.

The addPathTree method is called from update when enough time has elapsed after planting the last tree. It in turn calls the addTree method shown earlier with a different set of parameters where the tree gets placed in the selected path. The doTreeLogic method will return the tree to the pool once it goes out of view.

User Interaction

We are adding a listener to the document to look for relevant keyboard events. The handleKeyDown method sets the currentLane value if the right or left arrow keys are pressed or sets the bounceValue value if up arrow is pressed.

In update, the x position of our snowball is slowly incremented to reach the currentLane position there by switching lanes. 

Collision Detection

There is no real physics involved in this particular game, although we could use various physics frameworks for our collision detection purpose. But as you are well aware, a physics engine adds a lot of performance overhead to our game, and we should always try to see if we can avoid it. 

In our case, we just calculate the distance between our snowball and each tree to trigger a collision if they are very close. This happens in the doTreeLogic method, which gets called from update.

As you may have noticed, all trees currently present in our path are stored in the treesInPath array. The doTreeLogic method also removes the trees from display and into the pool once they go out of our view using the code shown below.

Conclusion

Creating a 3D game is a complicated process if you are not using a visual tool like Unity. It could seem intimidating or overwhelming, but let me assure you that once you get the hang of it, you'll feel a lot more powerful and creative. I would like you to explore further using the various physics frameworks or particle systems or the official examples.

How to Model a Low Poly Wolf in Cinema 4D: Part 2

$
0
0
Final product image
What You'll Be Creating

Follow this tutorial step-by-step to create a low poly wolf model that you can use in video games, graphic design and illustration projects whilst learning Cinema 4D quickly. 

Some of the skills you'll learn in this tutorial include creating basic 3D modelling, importing reference images, adding lighting to the scene and basic rendering techniques.

In the first part of the two-part tutorial, I showed you how to:

  • How to Import Reference Images
  • How to Prepare for Modelling
  • How to Model the Wolf Body
  • How to Model the Wolf Head

In this, the second part of the the tutorial series, I'll show you how to:

  • How to Model the Neck
  • How to Model the Legs
  • How to Model the Paws
  • How to Prepare for Rendering
  • How to Create a Background
  • How to Add Lighting and Render the Scene


5. How to Model the Neck

Step 1

The same technique that was used to model the head and the body will be used to model the fur for the neck. Use the Move, Scale and Rotate tool to position the Loft and n-Side.

Modelling the fur of the neck
Modelling the fur of the neck

Step 2

Duplicate the neck fur by holding the Control button on your keyboard. Click and Drag the new object to a new position.

Duplicating the neck fur
Duplicating the neck fur

Step 3

Continue to tweak the neck fur using the Move, Scale and Rotate Tools until you are happy with the results.

Editing the neck fur
Editing the neck fur

6. How to Model the Legs

Step 1

The same technique that was used to model the head, the body and the fur will be used to model the legs. Use the Move, Scale and Rotate tool to position the Loft and n-Side. You can use your reference image to help you with the shape and positioning of the legs.

Modelling the Wolfs leg
Modelling the Wolfs leg

Step 2

Switch to Perspective View. Select the leg and use the Move Tool to move it to the side of the Wolf's body.

Moving the Wolfs leg to the correct position
Moving the Wolfs leg to the correct position

Step 3

Select the first n-Side. This will be the n-Side that we will edit and manipulate (you can select the other n-Sides to manipulate as well). Use the Rotate and Move Tools to shape the leg.

Rotating the Wolfs leg
Rotating the Wolfs leg

Step 4

Once you are happy with the position of the leg, use the Symmetry modifier to create the second leg (using the same technique that was used to create the second ear)

Using symmetry modifier on the leg
Using symmetry modifier on the leg

Step 5

Repeat the steps above to create the front legs for the Wolf.

Created front legs of the Wolf
Created front legs of the Wolf

7. How to Model the Paws

Step 1

Create a cube by clicking on the Cube button in the top menu.

Select cube button
Select cube button

Step 2

Use the Scale Tool to scale the cube down to a suitable size for the paws.

Using scale tool on cube
Using scale tool on cube

Step 3

Make sure that the cube has been selected and click on the Make Editable button.

Clicking the make editable button
Clicking the make editable button

Step 4

Use a combination of all the different buttons on the side (Polygon, Points and Edges) to manipulate the cube. Remember that you create new polygons by having the Polygon button selected using the Move Tool (whilst holding down the Control button on the keyboard).

Modelling the paws
Modelling the paws

Step 5

Create the shape of the paw that you want by using a combination of all the different buttons on the side (Polygon, Points and Edges). You can follow the final paw shape in the image below for your reference.

Scaling the polygons of the paws
Scaling the polygons of the paws

Step 6

Duplicate the paw four times and use the Move Tool to place them in the right place underneath the legs.

Duplicating the paws and placing them in the correct positions
Duplicating the paws and placing them in the correct positions

8. How to Prepare for Rendering

Step 1

Select all the objects in the project by clicking on the first object (the text should change colour) and then holding the Shift Key on the keyboard and clicking on the last object.

Selecting all objects
Selecting all objects

Step 2

Press Alt > G on the keyboard to create a new group out of all the objects you have selected. Then rename the 'null' group to 'Wolf'.

Grouping all objects and renaming wolf
Grouping all objects and renaming wolf

Step 3

Create a new plane by expanding the menu from the Cube button at the top of the screen and selecting Plane.

Selecting plane from the menu
Selecting plane from the menu

Step 4

Make sure that the plane is selected and go into the object tab. From here you can edit the object properties to your liking (in this tutorial we have created a plane which is 4,000cm x 4,000cm with 20 x 20 segments).

Editing the plane
Editing the plane

Step 5

Select the Wolf group and use the Move Tool to move the Wolf above the plane. Try and get the paws to touch the plane or have them penetrate slightly. This will help with the shadows when we render the project.

Moving the wolf on top of the plane
Moving the wolf on top of the plane

Step 6

Create a new material by clicking on Create > New Material at the bottom of the screen. Double click on the new material once it has been created.

Creating a new material
Creating a new material

Step 7

Click on the arrow next to the Texture button and select Gradient from the drop down menu.

Creating a new gradient
Creating a new gradient

Step 8

Double click on the Gradient.

Selecting the gradient
Selecting the gradient

Step 9

Choose the colour of the gradient for the floor. For this tutorial we have chosen a dark grey gradient. Click on the drop down menu next to Type and choose 2D - Circular.

Selecting 2D - Circular from the dropdown menu
Selecting 2D - Circular from the dropdown menu

Step 10

Apply the gradient by clicking and dragging the material to the plane.

Adding the gradient to the plane
Adding the gradient to the plane

9. How to Create a Background

Step 1

Select the material and under the Projection drop down menu, select Frontal.

Selecting Frontal from the dropdown menu
Selecting Frontal from the dropdown menu

Step 2

Right click on the Plane and select Cinema 4D Tags > Compositing.

Selecting Compositing from the dropdown menu
Selecting Compositing from the dropdown menu

Step 3

Make sure the compositing tag is selected and tick Compositing Background.

Clicking on the tick box for Compositing Background
Clicking on the tick box for Compositing Background

Step 4

Select Floor > Background from the top menu.

Selecting Background from the menu
Selecting Background from the menu

Step 5

Apply the material to the new background. You can also click on Render to Picture Viewer to view how the background looks at this stage.

Adding material to the background
Adding material to the background

10. How to Add Lighting and Render the Scene

Step 1

Add a light object by clicking on the Light button on the top menu.

Selecting the light button
Selecting the light button

Step 2

Use the Move Tool to position the light above the Wolf. With the light selected you can also increase or decrease the intensity of the light in the options menu on the bottom left of the screen.

Moving the light object
Moving the light object

Step 3

Click on the Render Settings button on the top of the screen.

Clicking on the render settings button
Clicking on the render settings button

Step 4

Choose your output resolution.

Changing the settings in output
Changing the settings in output

Step 5

Choose the directory for the image and the file type. The image for this tutorial was rendered as a JPEG.

Changing the settings in save
Changing the settings in save

Step 6

Click on the Effect button. From the dropdown menu select Ambient Occlusion and Global Illumination.

Adding ambient occlusion and global illumination
Adding ambient occlusion and global illumination

Step 7

Click on the Render button on the top menu.

Clicking on the render button
Clicking on the render button

The End Result

Wait for the final render to finish. Once the render is complete you can repeat the steps above and change the camera for the viewport to create a new image from a different angle. 

Feel free to share your own creations below. You can also export your image into Adobe Photoshop to enhance it further or to use it as part of a larger image.

Final render of the low poly wolf
Final render of the low poly wolf


Platformer Mechanics: Moving Platforms

$
0
0
Final product image
What You'll Be Creating

In this tutorial you'll learn how to create moving platforms and make sure that objects that are riding them will preserve their relative position. We'll also handle the case of being crushed between a platform and the ground.

Prerequisites

This tutorial is based on the Basic Platformer Physics series. Specifically, we'll be using the code based on the 8th part of the tutorial as the starting point, with a few modifications. Check out the tutorial series, and particularly the last part. The principles behind the implementation will stand even if you're using a different physics solution, but the code will be compatible with the version presented in the tutorial series.

Demo

You can download the demo from the tutorial attachments. Use the WASD keys to move the character, Space to spawn a clone character, and P to spawn a moving platform. The right mouse button creates a tile. You can use the scroll wheel or the arrow keys to select a tile you want to place. The sliders change the size of the player's character.

The demo has been published under Unity 2017.2b4, and the source code is also compatible with this version of Unity.

Implementation

Moving Platforms

First of all, let's create a script for a moving platform.

Initialization

Let's start by creating the object's class.

Now let's initialize some basic parameters of the object in the init function.

We set the size and speed, and we make the collider kinematic, which means that it won't be moved by regular objects. We also set the mSlopeWallHeight to 0, which means that the platform will not climb the slopes—it'll always treat them as walls.

Behaviour

The behaviour for this particular moving platform will be just this: start movement right, and whenever you meet an obstacle, change the direction 90 degrees clockwise.

Here's the pattern visualized:

The pattern visualized

Gluing the Character to the Platform

Right now, if a character stands on a platform, the platform will simply slide from underneath it, as if there was no friction between the objects. We'll try to remedy that, by copying the offset of the platform.

The offset of the platform

Determine the Parent Object

First of all, we want to be aware of what object, if any, is our character standing on. Let's declare a reference to that object in the MovingObject class.

Now, in the UpdatePhysicsResponse, if we detect that we are colliding with an object below us, we can assign this reference. Let's create a function that will assign the reference first.

Now let's use it in appropriate places, that is wherever we say that our object is colliding with another object below it.

The first place is when we check if the objects are touching.

The second place is when they are overlapping.

Now that we've got this covered, let's handle the movement for our object. Let's modify the UpdatePhysics function from the previous tutorial.

Let's declare a class variable for the offset that we need to move our character.

Now let's replace the old local offset with the class one.

In case the object is on a platform, let's add the platform's movement to the offset.

Note that we're also checking here if we're still in touch with the object. If that's not the case then we set the mMountParent to null, to mark that this object is no longer riding on any other.

Next, let's move the position of our object by that offset. We're not going to use our Move function, but simply change the position. So in the collision check between the objects, which takes place right after the UpdatePhysics, we'll get the result for the positions in this frame instead of the previous one.

Now let's move to the UpdatePhysicsP2, which is called after the collisions between the objects have been resolved. Here we undo our previous movement, which hasn't been checked for whether it's valid or not.

Next, we proceed to UpdatePhysicsResponse to apply a move out of overlap with other objects. Here, previously we were modifying the position directly, but now instead let's modify the mOffset, so this position change gets resolved later when we use our Move function.

Now we can go back to the UpdatePhysicsP2, where we simply call the UpdatePhysicsResponse and Move functions as we did earlier, to get the correct position state.

Fix the Update Order

Because of the way we order the physics updates, if the child object is updated before the parent, the child will be constantly losing contact with the platform when traveling up/down.

Traveling up or down

To fix this, whenever we set the mMountParent, if the platform is behind the child in the update queue, we swap those two, so the parent object always updates first. Let's do that modification in the TryAutoMount function.

As you can see, if the update id of the platform object is greater than the child, the objects' update order gets swapped, removing the problem.

The order of the objects

That's pretty much it when it comes to gluing the character to the moving platform.

Detect Being Crushed

Detecting being crushed is pretty simple. In the UpdatePhysicsResponse, we need to see if the overlap against a kinematic object moves us into a wall. 

Let's take care of the X axis first:

If the object is on our right side and we are already pushing against a left wall, then let's call a Crush function, which we'll implement later. Do the same for the other side.

Let's repeat that for the Y axis.

The Crush function will simply move the character to the center of the map for the demo.

The result is the character being teleported when it's being crushed by a platform.

Being crushed by a platform

Summary

This was a short tutorial because adding moving platforms is not a big challenge, especially if you know the physics system well. Borrowing from all the code in the physics tutorial series, it was actually a very smooth process. 

This tutorial has been requested a few times, so I hope you find it useful! Thanks for reading, and see you next time!

Creating a Simple 3D Physics Game Using Three.js and Physijs

$
0
0
Final product image
What You'll Be Creating

In this tutorial, you'll learn how to use Physi.js to add game physics to a 3D scene created using Three.js. We'll create a simple game in which we drive a cart around collecting items, using basic physics shapes and physics constraints.

This tutorial will be building on top of the concepts shared in my previous Three.js tutorial. I would request you to read it if you are new to Three.js and to its 3D scene creation. 

Due to a technical limitation in hosting web worker based solutions on JSFiddle, we are unable to embed the interactive game in this tutorial page. Please use the provided source code to check out the working example on any cloud-based IDEs or by self-hosting.

1. 3D Physics on the Web

There are multiple frameworks and engines currently available which can be used to create 3D content for the web with physics. Some of those worth mentioning are Turbulenz, BabylonJS, PlayCanvas, and the obvious Unity WebGL build. But when it comes to popularity and ease of use, most people like to use Three.js for their experiments. As Three.js is a rendering engine and does not have integrated physics, we need to explore additional frameworks to add the physics capability.

A very popular JavaScript physics solution is Ammo.js, which is a direct port of Bullet physics. While directly using Ammo.js is possible, it is not very beginner friendly and has a lot of boilerplate code for each aspect. Also, as it is not manually written but ported using Emscripten, the code is not easy to understand. 

An alternative solution is to use Cannon.js or Physijs. The interesting thing with Physijs is that the focus is always on making things easier, which makes it the ideal choice for beginners. It is built based on Ammo.js and even has a Cannon.js branch. This tutorial uses Physijs and Three.js to build a working game prototype with physics capabilities. 

Yet another option, although oversimplified, would be to use the Whitestorm framework, which is a component-based framework based on Three.js and Physijs. 

2. Setting Up Physijs

We need to have the ammo.js, physi.js, physijs_worker.js and three.js files within our folder structure or coding environment to use Physijs. Physijs uses a web worker to use different threads for physics calculations. So the first step in the integration process is to set up the web worker as below.

At this point, the setup is complete, and we can start using the physics framework. Physijs has made sure that it followed the coding style of Three.js, and most of the concepts are simple replacements of the corresponding Three.js concept.

Basic Steps

Instead of THREE.Scene, we need to use Physijs.Scene.

There are multiple meshes available in Physijs which need to be used in place of THREE.Mesh. The available options are PlaneMesh, BoxMesh, SphereMesh, CylinderMesh, ConeMesh, CapsuleMesh, ConvexMesh, ConcaveMesh, and HeighfieldMesh.

We need to call the scene.simulate method to do the physics calculations either in the render method or within frequent intervals. Let me remind you that the physics calculations happen in a different thread and will not be in sync or as fast as the scene render loop. 

Even the next call to scene.simulate may happen while the previous calculations are still running. In order to make it properly in sync with the physics calculations, we could use the Physijs scene's update event.

In order to register a collision on a Physijs mesh object named arbitrarily as cube, we can listen to the collision event.

Within the above method, this will refer to cube, while objCollidedWith is the object cube has collided with.

3. Example Game Prototype

For this tutorial, we will be creating a very simple physics-based game where we will use physics constraints to create a vehicle. The player can use arrow keys to drive the vehicle and collect a bouncing ball which randomly appears in the play area. 

Interestingly, Physijs already has a special vehicle feature which can be directly used for creating vehicles, but we won't be using it.

The Game World

Our game world is a vast ground with walls on its four sides as below.

ground with walls

We use Physijs.BoxMesh for the ground and the four walls as shown in the code below.

Notice the usage of Physijs.createMaterial to create the necessary physics materials by passing a friction value and a restitution value. The friction value determines the grip on the ground, and the restitution value determines the bounciness. One important thing to note is that when we provide a mass value of 0, we create a stationary mesh object.

The Vehicle

We are going to create a special vehicle which has two connected parts. The front part, which has three wheels, acts as the engine, and the rear part, having two wheels, will act as a carriage. The carriage part is connected to the engine part using a hinge joint implemented using a Physijs.HingeContraint

The wheels use Physijs.DOFConstraint, which is a degree of freedom constraint to be attached to the vehicle's body while retaining the ability to rotate independently. I would invite you to read the official documentation on the various constraints available in Physijs.

The engine body and carriage body are simple BoxMesh objects like the ground shown above, but with a definite mass value. They are connected to each other using a hinge joint, as shown in the following code. A hinge joint restricts the motion of the connected object like that of a normal door.

The second part of the code applies limits to the rotation of the hinge, which in this case is between -Math.PI/3 and Math.PI/3

The wheels use a degree of freedom constraint which can be used to set limits on both linear motion and angular motion in all three axes. A method addWheel is created for adding wheels, which takes in multiple parameters. 

The parameters are the position of the wheel, the weight of the wheel, whether the wheel is big or small, and the wheel reference object. The method returns a newly created DOFConstraint, which is used for driving the vehicle.

The big wheels need to be attached to the carriage, and the small wheels are attached to the engine. The wheels are given a damping value so that their angular velocity gets reduced when no external force is being applied. This makes sure that the vehicle slows down when we release the accelerator. 

We will explore the driving logic in a later section. Each wheel mesh along with the car meshes are assigned the name of cart for identification purposes during the collision call back. Each wheel constraint has different angular limits, which are set independently once they are created. For example, here is the code for the front middle wheel of the engine, car.wheel_fm, and the corresponding constraint, car.wheel_fm_constraint.

The Ball

The ball is a Physijs.SphereMesh object with a lower mass value of 20. We use the releaseBall method to position the ball randomly within our game area whenever it gets collected. 

One thing worth noticing is the fact that we need to override the position values set by the physics simulation in order to reposition our ball. For this, we use the __dirtyPosition flag, which makes sure that the new position is used for further physics simulation.

The ball gets collected when it collides with any part of the vehicle which happens in the onCollision listener method.

Driving the Vehicle

We add event listeners for the onkeydown and onkeyup events of the document, where we determine the keyCode to set the values of the corresponding wheel constraints. The theory is that the single front wheel of the engine controls the turning of our vehicle, and the two wheels on the rear of the engine control the acceleration and deceleration. The wheels on the carriage do not play any part in the driving.

The DOFConstraint uses the enableAngularMotor method to apply angular velocity on the wheel which turns the wheel based on the axis value provided as a parameter. Basically, we only turn the wheels, and the motion of the vehicle happens due to the frictional response of the ground, as in the real world.

the completed game

We are unable to embed the working game in this page as mentioned at the start of the tutorial. Please go through the complete source to understand how everything is wired together.

Conclusion

This is a very simple introduction to implementing physics in your Three.js 3D world. The Physijs documentation is sorely lacking, but there are many examples already available which are worth looking into. Physijs is a very beginner-friendly framework, like Three.js, when you consider the complexity that is present under the hood. 

JavaScript is clearly popular for game development as well as web development. It’s not without its learning curves, and there are plenty of frameworks and libraries to keep you busy, as well. If you’re looking for additional resources to study or to use in your work, check out what we have available in the Envato marketplace.

Hope this tutorial helps you get started in exploring the interesting world of 3D web game physics.

Importing an Animated Character Into Unity 3D

$
0
0
What You'll Be Creating

Unity 3D is one of the most popular open-source game engines available today. Along with an easy-to-use interface, it allows you to import files from most major designing programs, such as Maya (.mb or .ma), Cinema 3D (.c4d, .c3d), Studio Max (.max), and Blender (fbx.). 

At first, importing a character into Unity can seem intimidating. In this tutorial, I hope to make it simple, so that you may bring your carefully sculpted character to life!

Finding Free Animations

If you have created your own animations, that's awesome—we will discuss importing them into Unity shortly. If you've created your character or would like to purchase a stock character, let's talk about where we can find some. 

Mixamo is a great option (recently purchased by Adobe). They provide basic free animations and custom bone rigging that can animate your character in minutes. Once you sign up, you can choose different characters and animation kits. Separately, you can use the free preset animations from Unity or purchase animation packages from the Unity Asset Store.

Mixamo Homepage

Open Unity

Open Unity

Since this tutorial is about importing an animated character, we won't get into the specifics about Unity. Let's open Unity by starting a new project. 

Tip: Unity understands the T-Pose, so before importing your character, aim to save him in a default T-pose. 

Preparing Your World

Start a new folder

Your character may have many different components, and that's why it's important to create a new folder. Right click on the Project Window > Create > New Folder. For the purpose of this tutorial, let's name it character

Add a plane

Now let's add a plane for our character to stand on. Go to GameObject >3D Object > Plane. We will also need to adjust the camera by moving the arrow for a better view. 

Adjust the camera

Importing Your Character

Time to import your character. Click and drag your character's file (fbx, cd3, etc.) into the folder you created in Unity. All of your character's elements, including materials, will be imported into the same file.

Imported character

Setting Up Your Rig

To set up the rig, right click your character and choose humanoid. A new window will open with your character, and this is where Unity attempts to match your character's rig (muscles and bones). 

Rigging your character

A good rig match will show in green. See the example below.

Rig Match

After your character is configured, click Done and Configure. Save your scene. We can now drag your character into the game world.

Save scene after configuration

Animator Controller Basics

Time to add his animation. Go to Create > Animator Controller, and name it MyController.

Adding an Animator Controller

After you add the animator controller, you will see a new tab. This is where we will add our character's animation. You may have multiple animations, but for the purpose of this tutorial we will talk about adding one. Each State (box) will represent an animation.

Adding animation to the controller

Click on the clock to the right of Motion. A window will open with your imported animations, so click and drag one into that box. 

Tip: The default animation will be in orange.

To edit your animation settings, double click on the State. A box will open under the Inspector Window. Here you can edit the speed and loop time if you wish your animation to loop.

Adding a Transition

When you right click on a state, you can create transitions. This is used for multiple animations—for example, walk to run. Let's right click and create a New State, and then add a transition from Entry to New State. See the example above.

Tip: You can use your middle mouse button to zoom in and out.

Adding the controller to the character

Go to the Scene tab and click on your character. You can now drag your animator controller into the controller box in the Inspector Window. See the example above.

Let's Play

In conclusion, you should now have an understanding of how to import and add an animation to the animator controller. 

Time to see our character in action. Click the Play button on top of the Scene Window. Congratulations! You have just imported your animated character into Unity!


How Tuts+ Has Helped People in Their Careers

$
0
0

People use Envato Tuts+ for all kinds of reasons. Sometimes it's just for fun or to pick up some creative skills as a hobby. But many people also use the site to help them in their careers. 

We ran a reader survey earlier this year, and some of the responses were quite inspiring. Here's a look at how some of your fellow learners have used the site to help them make progress in their careers.

Landing Their First Job

Quite a few of our learners are students who use Envato Tuts+ to help them supplement their formal school or university education with some extra practical skills.

Bartłomiej Szubert was one of those people. He started to learn web development from our courses and eBooks while studying, and after a few months he prepared his CV and applied for a web developer position at a company in his city. And he got the job!

Right now I'm a Mid-Level PHP Programmer / Senior Web Developer in another company, while my colleagues from university often haven't even found their first job. And that's all thanks to Envato Tuts+.

For Pouya Rezaei, it was after graduating from university in Economics & Finance that he realised he wanted to work in a different field. So he set out to teach himself everything he needed to know about designing websites. 

Two years later I began freelancing, six years on I am creating websites, design work, PHP, HTML, JavaScript ... Everything I learnt and all the CMS plugins I used for my clients when I first started, it ALL was with the help of you guys. I'm living my life doing what I LOVE. 
Pouya Rezaei
Pouya Rezaei

Humaira Mahinur only started on the site a few months ago, but has already learned a lot and is moving towards a freelance career. 

I am a learner of web design and development, graphic design and other skills ... After completing some projects, by the will of Allah, I will start my career with Envato Studio and some freelance marketplace. 

And Michelle Silva is a graphic design student about to graduate and now working in a printing job to gain some experience. 

This website has definitely helped me improve in areas that I didn't understand or weren't covered in class and need to learn quickly to complete a job. Tuts+ guarantees that the ONE course you watch will help you learn what you need. 
Michelle Silva
Michelle Silva

Finding Better Job Opportunities

Sometimes, people are already on the career ladder, but are not satisfied with the opportunities available to them in their current roles. 

Jenny Yamada, for example, says:

I'm using it to refresh my memory and apply for jobs I wouldn't qualify for otherwise. I was able to build out my website in WordPress from taking Adi's course. 

But you don't always need to move on to move up. Alexander Kozhurkin was already working as a full-time developer, but felt stuck at a junior level. By learning new skills, he was able to start working on more fulfilling projects.

Now I'm working on an enterprise-level business app. I realized that my success depends on my own efforts, and quality education is the key for this. Envato courses let me grow fast, it's like watching an expert coding over his shoulder. 

Making a Career Change

Envato Tuts+ is also helping people retrain so that they can make the career change they've always dreamed of.

Some, like Dave Perlman, are still in the early stages of a career change, but have accumulated skills that are moving them towards a dream job:

I'm closer now than I ever have been to having a career as a web developer and I've only put in about a year learning code.

Others are further along. Treighton Mauldin took a big risk several years ago by quitting his job in the construction industry to pursue a career in web development. 

I had no experience, and no clue where to start. When I found Tuts+ I was able to start learning rapidly, going through the free courses and tutorials, and within a year I had my first full-time job as a developer. Now I am a back end developer and am helping lead a development team of four people. 
Treighton Mauldin
Treighton Mauldin

Another person who switched careers with the help of Tuts+ is Traci Brinling. After being laid off three years ago, she decided to follow her passion for animation and break into a new career. She used our online courses and tutorials to help her make the change.   

I did something right because I am working as an in-house animator and now just trying to build up my freelance client base. 

Meanwhile, Neeru Mokha is using the site to help her get back into work after a career break.

It's really helpful in updating my resume as I took 4 years of break but now I am getting very close to filling my gap. Videos posted are very knowledgeable and very helpful in improving your basic to advanced level skills.

And so is George Millard:

I have got back into software development after a number of years working in a different field. I am using it to get back up to speed and learn the new languages that are now popular.

Being More Effective as a Freelancer

Many freelancers use Envato Tuts+ to brush up on their skills and land better contracts. When Christian Nazha had a client ask for a Laravel site, he tried various other sites to get the information he needed, but none could help him. Some had bad English, poor sound quality, or even skipped the basics. 

Here I found the perfect combination of explanatory and quality videos.

Meanwhile, self-taught web developer Tracey Niblett is using Tuts+ to improve the quality of her work, resulting in big cost savings. 

Tuts+ has really helped to fill in the gaps in my knowledge so that my code has become more efficient and reliable. Reliable code means happy customers and less time supporting and more time developing new stuff so the money I have saved in time supporting has more than covered the cost of my subscription.

Being Their Own Boss

Lisette Marie McGrath has been struggling to set up an online business while grappling with health issues. The online courses and tutorials have helped her to keep her skills updated while working at her own pace. Now her health is improving and she's able to devote more time to her business, using the skills she's acquired.

Envato Tuts+ has kept me going for the last few years, keeping me interested, inspired and focussed on what matters the most to me.

Meanwhile, Martine Kerr says she went from 813 to over 10,000 Instagram followers in just over a year with videos she's created using skills learned on Tuts+, and now she's ready to design and film her own courses.

The skills allowed me to save a huge amount of time in filming and basic editing workflow. I'm now confident enough to create my own online courses.

Doing a Better Job

And finally, what better way to enhance your career than just being better at the day-to-day job you do?

Cassie Porcella got her first job as a corporate web developer/designer five years ago, and she used Tuts+ to help her thrive in the new role. When she started, the company website was very basic, and she used our courses and tutorials to learn the skills she needed to overhaul it.

I quickly started using Tuts+ and it helped me take my coding from basic HTML and CSS to full PHP, MySQL and JavaScript/jQuery. After a full redesign of the site design and architecture to align with our business objectives, I started using Tuts+ to refine the site and add user-friendly features. 

But as we all know, technology is an ever-changing industry, and a couple of years ago, Cassie updated her knowledge with the help of Kezz Bracey's explanations of responsive design

This course helped me to transform our site and its usability and help future-proof the design structure for the multitude of device sizes. Additionally, it really encouraged me to see a female coder getting recognition in a field where us gals are often the minority. Thanks for providing such helpful tutorials that have helped me excel in my job, which benefits my company, our team members and our customers! I look forward to refining my craft and boosting my skills with your help! 
Cassie Porcella
Cassie Porcella

Over to You

How have you used Envato Tuts+ tutorials and courses? Have they helped you in your career? Let us know in the comments below. 

If you haven't tried our full membership yet, why not give it a go? As you can tell from these stories, many people enjoy the kind of career progress that quickly pays for the cost of the subscription. Try our new combined subscription to Envato Tuts+ and Envato Elements. For just $29 a month, you get unlimited video courses and eBooks, plus unlimited downloads from a huge library of professional-quality graphics, photos, web templates, and much more.

Join Envato Elements for Just $19!

$
0
0

We're excited to share a one-day promotion for Envato Elements. Usually $29, for one day only you can lock in a lifetime price of just $19 per month!

What is Envato Elements?

Envato Elements provides inspiring and ready-to-use photos, templates, fonts, assets, icons, and much more. For a single monthly fee, you get unlimited downloads to use in your projects and design work.

Now with over 33,000 beautiful design templates and assets (and over 300,000 photos), it's the only design subscription you'll ever need.

Not only that, Envato Elements now includes access to every Tuts+ course and eBook. That's over 1,000 courses on web design, code, and graphic design, as well as the entire A Book Apart and Smashing Magazine eBook libraries!

How Can I Join for $19?

Head over to Envato Elements any time today, and you can take advantage of a one-off discount, for the lifetime of your membership. Join today for $19 and you lock that price in for all future months.

Act fast, though. The promotion ends tomorrow, at 12pm Wednesday 19th October, AEST (Australian time). You can see the end time of the promotion in other time zones, to make sure you don't miss out!

How to Create Realistic Water in Unity

$
0
0
Final product image
What You'll Be Creating

Unity is a multi-platform game engine developed by Unity Technologies and is used to create video games and applications for several devices such as consoles, mobile devices, computers, and even websites. Unity's core advantages are its robustness, portability, and community; Unity targets several well-known APIs such as Direct3D, OpenGL, OpenGL ES, and the recent Vulkan.

Due to the aforementioned characteristics, Unity has become more and more popular among AAA software development houses and aspiring game programmers.

Unity supports several technologies and components. One of the key components is the Water system. Unity's water system allows you to add different types of water into your application or game, namely Water Basic, Water Pro, and Water4. By default, Unity includes several water prefabs (including the necessary shaders, scripts, and art assets).

This tutorial will focus on explaining how the water in Unity works, and how to use it to create vast and rich terrain environments.

Prerequisites

First, ensure you are using the latest version of Unity; otherwise, you may find small differences following the tutorial and using the physics joints.

To start this tutorial, you have two paths to choose from:

  1. Start it right away using the available Starting Project.
  2. Complete the previous Unity tutorial called Unity Terrain tools.

Either way, we will get you covered, but taking your time and starting in the previous one will give you more insights about Unity and its tools.

Water Basic

I'm assuming that you either started by using the current Starting Project or you have finished the previous Unity Terrain tools tutorial. If that’s not the case, you can start a new project, but you must import the environmental asset package and create your own terrain. If you are using a new project, go to the main menu, Assets > Import Package and select Environment.

From now on, the tutorial is focused on the current Starting Project. By analysing the terrain, you can see that, in the center, the ground is a little bit deeper. That area was created specifically for you to create a lake. One way to do this is using the Water Basic prefab.

WaterBasic - Starting point

In the Project tab, open the Assets folder and then open Environment. Here you will find two water folders: Water and Water (Basic). Initially, you will work with Water (Basic). Open it and then open the Prefabs folder. Two prefabs are available: WaterBasicDaytime and WaterBasicNightime.

WaterBasic - Prefabs

Before moving on, here's a quick explanation of prefabs. A prefab acts as a template of a game object. It allows you to create new object instances in the scene, and any edits made to a prefab asset are immediately reflected in all instances produced from it. 

However, you can also override components and settings for each instance individually. This can be quite helpful if you need to have several objects of the same type in a scene or in several scenes. By using prefabs, you don’t need to create every single object from scratch, and if you want to make an adjustment to it, it will automatically update all instances.

As you may have guessed by the names, you should use WaterBasicDaytime if you have a scene during the day, and you use WaterBasicNightime in nighttime scenes. Both of them work in exactly the same way, but the second one is set to be darker.

In this project you have a daytime scene, so you are going to use the WaterBasicDaytime prefab. Select the prefab with the mouse, and drag it to the scene (more or less into the hole in the ground, similar to the next figure). This will add the WaterBasicDaytime to the scene.

Next, select the water and adjust its Position and Scale.

WaterBasic - Position and shape

When you have the water positioned and configured as you want, let's take a quick look at what you can do with it. If you select it and go to the Inspector tab, you will see several components: a Transform component that you have just used, a Water Basic Plane (Mesh Filter), a Mesh Renderer where the Material for the water is set, a Water Basic Script, and a Shader.

WaterBasic - Inspector Properties

Inside the Mesh Renderer, you can change some options related to shadow generation like Cast Shadows or Receive Shadows. You can also modify several properties related to reflections. Set Cast Shadows and Receive Shadows to On. Next, for Reflection Probes, let’s set it to Blend Probes And Skybox.

WaterBasic - Mesh Renderer

The WaterBasicDaytime Shader lets you set some parameters for the water, like the Wave scale and the Wave speed. You can play with those values to see some graphical changes, but for now leave the default values.

WaterBasic - Water Basic Day Time

Now, in order to see the final result, place the camera in a good position. To do that, move to the Scene view and, once you have the view you want, select the Main Camera game object. Now go to the menu GameObject, and select Align With View. This will place the camera in the position you want. Press play.

WaterBasic - Final Result

From here, you can go back and change the prefab properties to see the differences between properties. Play with Cast Shadows, Wave scale, and Wave speed to sense the modifications.

Water Pro

The next step is to learn how to create and configure a lake using Water Pro. Before moving on, delete the WaterBasicDaytime game object from your scene.

Next, in your Project tab, open the Standard Assets folder and open Environment again. This time, open the Water folder. Inside you have two folders: Water and Water4. In order to use Water Pro, you must open the Water folder. Next, open the Prefabs folder.

Water Pro - Prefabs

Just like with Water Basic, you have two prefabs in the folder: WaterProDaytime and WaterProNightime. Both of them work in exactly the same way, and as aforementioned WaterProDaytime is set for daytime scenes, while WaterProNightime is set for darker environments.

Since you have a daytime scene, you should choose WaterProDaytime. Select the prefab and drag it into the scene. Again, select the WaterProDaytime game object and adjust its Position and Scale.

As soon as the lake gets a good size, you will instantly see differences in the graphical quality of the water compared to Water Basic.

Water Pro - Adjustments

When you have the water in place, please take a quick look at what you can do with it. If you select it and then look at the Inspector tab, you will see several components: a Transform component, a Water Plane Mesh, a Mesh Renderer, a Water (Script), and a Shader.

Water Pro - Inspector

The Mesh Renderer properties are similar to the previous one. Set both Cast Shadows and Receive Shadows to On. Next, change Reflection Probes to Blend Probes And Skybox.

The water Script presents further properties that can be modified. These properties are not available for the previous water type.

Water Pro - Scripting

You can set the Water Mode to Simple, which will make the water work like the basic water, to Reflective, which will make the water have reflection but no refraction, or Refractive, which allows both reflection and refraction. You can Disable Pixel Lights, which will reduce the quality of lighting in the reflection/refraction in order to gain an increase in performance. 

You can set the Texture Size, which refers to the resolution of the generated water texture. The Clip Plane Offset value is the distance below the water that the reflected or refracted image appears. You can set the Reflect Layers affected as well as the Refract Layers. These are layer masks that control which scene objects are visible in the water. By default, all layers are selected.

In the Shader component, you can change the Wave Scale, and change the values of Reflection and Refraction Distort. These will determine the apparent height of the ripples in terms of their effect on reflected or refracted objects.

You can also set the Reflective color of the water to control the tint that will be applied to objects underwater.

Water Pro - Reflection controls

If you press play, you can see your Water Pro in action. This is a way more realistic water than the Water Basic; however, in terms of computational power required, it is also more intensive.

Water Pro - Final Result

Water4

To test Water4, you need to delete the lake you have just created. 

In your Project tab, open the Standard Assets > Environment. Open the Water folder and then the Water4 folder. Next, open the Prefabs folder. Here you find two prefabs: Water4Simple and Water4Advanced.

Water4 - Prefabs

If you select the two prefabs and compare them, you will notice that they have the same components and work in exactly the same way. Then what’s the difference between the two?

Well, you can see that by selecting the water material they use. The advanced version includes additional Shore and Foam textures. These textures are applied on the crests of waves and also where terrains and other objects interrupt the wave mesh, like the shore.

Select the Water4Advanced prefab and drag it into the scene. The next thing to do is to adjust the Position and Scale of the water plane.

Water4 - Adjustments

Note that when you add the prefab, Unity will automatically create a reflection scene game object. This game object allows you to change the water reflection in your scene. The camera component on reflection game object allows the Water4 to reflect your scene.

Water4 - Inspector

Now, if you select the Water4Advanced game object, you will see that you have several properties that you can change.

Water4 - Inspector Scripts

The first field in the Water Base (Script) component allows you to define a material for your water. You can also define the Water Quality as Low, Medium, or High. If the EdgeBlend option is enabled, Water4 will blend the edges of the water mesh.

The next component is Specular Lighting. This script adjusts the specular quality of the water. As you can see, it has a reference to specular game object transform. You can use a reference to indicate any transform of a specular light source. This can be, for example, your directional light transform.

Next you have the Planar Reflection component. This one is used for real-time planar reflections. The reflections are calculated in relation to the height of the parent mesh that has this script attached. You can set several parameters as the reflection masks, turn reflect skybox on or off, or define a clear color. Let’s just leave these with the default values.

Finally, you have the Gerstner Displace component, which allows you to control wave generation.

If you press the play button, you can now see the Water4 in action, creating a lake in the center of the terrain.

Water4 - Final Result

Conclusions

This concludes the tutorial about Unity Water. You learned about the three main types of water: Water Basic, Pro, and Water4. With this knowledge, you can now create new rich environments, or modify and improve current ones, for your next cutting-edge game or application.

Unity has an active economy. There are many other products that help you build out your project. The nature of the platform also makes it a great option from which you can improve your skills. Whatever the case, you can see everything we have available in the Envato Marketplace.

If you have further questions or comments, as always, feel free to drop a line in the comments section.

Class Design in Games: Beyond RPGs

$
0
0

Classes are everywhere. Once the domain of RPGs, now class systems have been pushed into every type of game imaginable. We're all familiar with the tropes of Warriors and Wizards in high fantasy, but what can we learn about class design from other games?

The first question we need to ask ourselves is, "What exactly is a class?" The term is pretty loosely defined in gaming, and there are several correct answers. In an RPG like Dungeons & Dragons, classes are defined by the rulebook and present a list of abilities your character can have access to. 

If you want to be a stealthy assassin or a shapeshifter, you need to choose an appropriate class. The thing is, there are other choices you can make as well: choosing your race (elf or dwarf) and background (criminal or noble) which also affect your gameplay options. What exactly is the difference between race and class? If your character can breathe fire because they're a half-dragon, is that any different from being able to shoot magic flame from your hands? We really have to look at these things as variations on the class concept.

So when we're discussing classes, we'll be talking about not just standard RPG classes and races, but Starcraft armies, Street Fighter characters, and even Mario Kart vehicles. It might seem odd to lump all of these in the same box, but they all share something simple: a choice you make outside of the game which determines your gameplay options within the game.

Age of mythology image
Age of Mythology divides its classes into races, and then further as individual gods.

Why Use Classes?

So why even bother with classes? What do they add to a game? There are a lot of reasons, but one of the simplest is adding content. More classes = more ways to play the game = more ways to have fun. When you look at World of Warcraft, it's not uncommon to see players with several high-level characters. 

Tails was so popular as an additional character in Sonic that they later added Knuckles, Shadow, Cream, and countless others. Dungeons & Dragons has a multitude of classes available for players, spread out throughout optional rulebooks. At an extreme level, some games exist solely because of their variety of classes—imagine Smash Bros with Mario as the only character. Fighting games are fun largely because of the way different characters interact, meaning that every matchup has different strategies.

Another reason classes are useful is because they promote diversity. This is especially important in competitive multiplayer games, where (generally speaking) everyone wants to be the best. If you wanted to make an MMO where players can assign points to their skills, you might think that the playerbase would create a range of different character types. What inevitably happens, though, as shown over and over by MMOs like Ultima Online, is that players gravitate towards "best builds". 

Generally, a small selection of players who are experienced at the game will do the math and post optimal builds, and everyone else will just copy that. This "copy others" attitude isn't unique to MMOs (Magic: The Gathering players have debated for some time the pros and cons of "netdecking"), and any game where you can choose your skills will have at least some discussion on best builds.

Of course, creating classes doesn't stop the issue—World of Warcraft, despite having multiple classes, has plenty of build discussion—but it at least creates a little bit of variety. Instead of having a single "generic tank build", you might have a choice of playing a warrior tank, paladin tank, or druid tank. 

And lastly, it reduces the gap between skilled and unskilled players. Being a new player to a game can already be frustrating when everyone is better than you, but if everyone is also using better characters then it can feel doubly frustrating. New players might feel as if they are being punished for their lack of knowledge, whereas pro players might spend their time trying to find abusive build combinations. 

New players also run the risk of "doing it wrong" by spending points on useless skills—the idea of "noob traps" is something we've discussed before. By forcing players into predesigned classes, you refocus the game back onto the gameplay, and away from character building.

So are there any problems with classes? Well, obviously it can be a massive time investment. But from a design perspective, there's really just one issue: class systems limit a player's ability to experiment with fun builds or create specific ideas. Players love to be creative, and limiting that creativeness can limit the amount of fun to be had. 

For highly competitive games, it can be argued that "design your own" systems are an extremely dangerous idea, as all it takes is one overpowered combination to ruin the whole thing. But for some games, character creation is what makes the game fun in the first place.

Impossible Creatures image
Impossible Creatures, an RTS where players can fuse creatures together to create their own armies and engage in Mad Scientist combat. 

So, assuming we do want to add classes, how do we go about designing them? Well, it's such an expansive concept that even if we limited ourselves to a particular genre, we could write a novel and still only scratch the surface. So let's focus instead on some general common issues that apply across the board.

Strict vs. Loose Class Design

The word “class” means many things, so let's introduce a new concept: the idea of strict and loose classes.

  • A strict class is one that defines a player's available skillset.
  • A loose class gives more limited powers or bonuses to certain playstyles.

Generally speaking, the more complex a system is, the more likely it is to be strict.

In Diablo 3, players can choose from classes like Barbarian, Monk, and Wizard. These classes have special abilities, and those abilities define what the character can do. Only the Monks have Cyclone Strike, and only Wizards have Hydra. The classes gain specific skills at specific levels, and can never learn skills from other classes. Diablo 3 is very firmly a strict system.

Compare to a game like Desktop Dungeons, which is a loose system. When a player chooses a class, it simply gives that player a minor advantage: Berserkers have 50% magic resistance. Priests deal double damage to undead. A Berserker can still do all the things a Priest does, but is better (or worse) in certain situations.

Obviously, there is no clear distinction between "strict" and "loose", and there will be games which can be argued to be in either camp. Vampire: The Masquerade allows players to choose a clan, and although each clan has unique powers, these powers do not define the character and the game otherwise operates like a standard point-buy system. 

But what of other genres? Well, Hearthstone allows players to choose a class, and this gives them a class ability they can use in game, such as producing minions or drawing extra cards. Since this ability only gives a minor advantage in game, it counts as a "loose" class advantage.

However, Hearthstone also has class cards which can only be used by certain classes. Cards like Backstab or Sap are Rogue-only cards, but are theoretically useful for every class. This limiting of cards means Hearthstone is "strict" class design, as every class will have a variety of options unavailable to other players.

So why does this all matter? Well, the stricter a game is, the more pronounced the benefits of a class system are (as discussed above in “why use classes”). More variety between classes, fewer “noob traps”, more fun for players. Additionally, strict design allows you to create incredibly flavourful classes. In Hearthstone, playing a priest feels like playing a priest (or at least, as close as you can get in a card game). Each of the classes feels distinct, and this distinctness allows the player to play the game in a variety of different ways (hopefully finding one suitable to their playstyle).

The downside is, of course, the same downside mentioned above—that the player is limited to the playstyles defined by the developers. It doesn't really allow for exploration beyond that. And because each class has a certain playstyle, there are times when you're going to know how the game will play out before the first move is made or card is drawn. 

This can be pleasant (if you're winning), or frustrating (if not). If you struggle to beat rogues and continually get matched against them, the game can become unfun very quickly. Depending on what playstyles or meta is popular at the time, it might mean playing a string of games against not just the same class, but the same deck or character build—which can be pretty underwhelming.

Mechanical design is just one aspect of character creation, however. We need to ask what players want from their games, and there are several answers. For most new players, they're not thinking about the mechanics behind each class—most often, they want to play the cool soul-stealing ninja, or the alien that eats face. This side of character design, which includes things like backstory and visual design, is often referred to as "fluff" or "flavour". It's an important part of the design process, but it's enough of a topic by itself that we'll have to leave it for another time.

The other question players most often ask is, "Well, what does it do?" Sometimes the answer is obvious, sometimes less so—but generally, the player will be trying to find a class which allows them to play the game in the way they want.

South Park Stick of Truth image
South Park's "Jew" Class is a non-standard class with powerful lategame abilities.

Fulfilling a Role

Generally speaking, the purpose of a class is to allow the player to play the game in a way that they enjoy. Not everyone enjoys playing magic classes, so it's important not to force players into roles they don't enjoy. Of course, for multiplayer games, some players will be pressured into playing certain roles, but generally speaking players will play whatever is the most fun.

In certain games (like MMOs), the ability to fill a role becomes doubly important. If your party is planning to fight the Dragon Emperor, then you probably need to have a strategy. Typically, tank/damage/healer roles are primary, with other roles such as controller, leader, tracker and so forth dependent on the game. 

Because available party slots are generally limited, it's important that your team is able to get the most out of its available party slots—all healer parties tend to do poorly. Players will want to choose roles that complement each other to maximise their chances of success, and this means giving the players the option to choose classes that they enjoy and feel are useful to the team.

Regardless of the game style, you want to create classes that allow for an enjoyable gameplay experience. The classes you design will determine how the game is played. If all your characters are swordsmen, then gameplay is going to be focused on close quarters fighting. If you add a single sniper to the game, then suddenly the whole dynamic changes—environment and cover suddenly become more important, and rushing around in the open is no longer a viable tactic. 

You need to understand what you want from your game, and the roles and abilities you have should promote that gameplay style. If you don't want a role being fulfilled, then simply don't add it to your game. Don't like the idea of healers slowing down gameplay? Remove them. It's your game, so there's no reason you have to stick to "traditional" design roles.

Despite many games using the traditional tank/dealer/healer design, there are plenty of reasons to avoid it. The most obvious is that if you design your game around those classes as a central idea, anything which does not fit into those criteria is bad. Imagine a Warrior, Rogue and Cleric being joined by a Banker or Farmer. There's no reason that players shouldn't be allowed to play those alternative classes, but the chances are they have no place within the "holy trinity" framework. Classes not only have to be balanced with each other, but within the game itself.

Balancing the Classes

Sometimes, however, we can get obsessed with concepts like balance—making sure every class is fair to use. While for some games this is necessary, it's not necessary for every single game. Bad classes can provide extra challenge, or a balancing factor for experienced players. The Binding of Isaac's "The Lost" can fly, but dies in one hit. Street Fighter's "Dan Hibiki" is a popular joke character. These "bad classes" are simply more options for players who choose to challenge themselves. Additionally, if every class is perfectly balanced, then what does it matter which one you choose? 

We should also ask what we're balancing for. Do we balance based on win rates? Or how they compare for 1 on 1 combat? Some games, MMOs in particular, struggle to keep characters balanced between the PVE and PVP elements. In the Binding of Isaac, damage is often considered a "god stat" for characters—not only is it incredibly handy to be able to one-shot everything in sight, but the game rewards fast play with secret bosses and going unhurt with "devil items", powerful items that serve to snowball a good character even further. The slower, tankier characters like Magdalene look fine on paper, but simply can't compete with the bonuses that high-damage characters get. Whereas The Lost is an interesting character because of intentional difficulty, Magdalene is simply a boring character.

Binding of Isaac image
The Lost, one of the many characters from The Binding of Isaac.

League of Legends embraces this and uses an idea called “perfect imbalance” to keep gameplay fresh. The game is incredibly complex, and trying to balance over 130 characters is basically an impossible skill. Not only do the designers have to contend with how the characters interact, but every time a small change is made it could theoretically throw everything out of balance again. 

They try to ensure that no single character is overpowered, but there are plenty of "bad characters"—and due to the evolving of the game, sometimes characters which are seen as bad suddenly become viable. The complexity and ever-changing nature of the game mean that players are constantly forced to re-evaluate the best strategies, ensuring that gameplay is never "solved".

"Solving" is a problem for many games. When you look at classes, sometimes you can put down all the abilities on paper and work out what exactly each class is capable of. What this means is that in team games, classes are often judged by a single metric: how much damage you can output, how quickly you can heal, or how quickly you can race to the end. Your character has one job, and the best character for that job is whoever has the highest numbers. This raises an interesting question: is it better to have a class that is exceptional at just one task, or to have a class that can do everything satisfactorily? 

Specialisation vs. Flexibility

When we create a class, we should generally have a rough idea of what we want from it. In an MMO, the perfect tank is basically a granite boulder—something that will just sit there and soak up damage while the rest of the team throws flaming death. This creates a sort of "arms race" which means the most specialised characters are (almost always) the best ones for the jobs.

The problem with this is that if one character is the best at the job, every other character is (by default) not the best—and why would you intentionally play a bad character? This is a problem for MMOs who are trying to juggle balancing dozens of character classes. Why play a rogue if mages have better DPS? 

Imagine making a game, similar to Civilization, wherein you try to take over the world. You can achieve victory through political, military, or cultural might. You can also choose a race, and each race has a benefit: elves are better at politics, orcs are good at military, and so forth. Why would a military fan ever choose anything other than orcs? Also, if you're playing against orcs, why would you invest into political defence? The specialisation of the races restricts your playstyle and forces you into certain options.

Civ 6 image
The races in Civilization IV encourage players to use certain tactics without forcing them down any particular avenue.

This is the biggest problem with specialised classes. If specialisation is doing one thing well, then it means not doing anything else. If choice is a core component of gameplay, then doing the same thing over and over again is bad design. This is a problem many games face, and it's a problem especially with regards to healing classes.

So what's the solution? As we discussed in the healing article, you need to make sure the player has a range of options available during the game. It's one of the most fundamental aspects of game design: keep the player engaged. If the player doesn't have to make any choices for their actions, then they're not engaged, and that's when things become boring.

So when you make your class, make sure they're able to participate in the game at all times. If you're designing an RPG, make sure the classes all have skills for both inside and outside of combat, rather than creating a “skill-monkey” character. If you're designing a game with multiple paths to victory, try to make sure each race has the option of winning in different ways. 

Allow players to adapt to the flow of the game, and if they realise they need to change tactics, allow them. The more specialised a class or race is, the more likely it can only do one thing, and the more likely it is to get stuck doing that thing over and over again. Choice is important.

Soft and Hard Counters

Players like to win. In a competitive, class-based game, players will generally choose the best class. Best is often subjective—it depends on the player's skill, playstyle, the map, and even recent gameplay changes. For most players, "what is best" is really just "whatever beats your opponent". 

For some games, this means trying to anticipate what your opponent is going to play. For CCGs like Magic and Hearthstone, players talk about "the meta"—what the most popular decks are and what cards your opponents are likely to be running. A player might choose to play a deck specifically to beat the meta, running cards that shut down certain decks. In magic, some deck archetypes can be entirely shut down by a single card, meaning that playing the meta can be an effective way to win.

In other games, players take turns "drafting" their characters. Knowing what your opponent has chosen means that the ability to choose a counter becomes especially important. The tactic of trying to pick a character or class specifically to beat your opponents is known ascounterpicking.

Having counters in games is generally a positive mechanic. It allows a certain amount of self-balancing from the players themselves, as any player who uses an overpowered class can expect to hit a higher share of counter-classes. The existence of a meta-game allows players to discuss the best tactics, the best counters to those tactics, and the best way to play in the current environment.

The question is then to what extent counters should be effective. Generally, counters fall into the category of “soft counters” and “hard counters”.

Soft counters are classes that have a slight bonus against certain character types. High mobility characters are generally a soft counter to snipers—although the sniper can win, they need to be skillful or lucky to stand a chance.

Team Fortress 2 image
Team Fortress 2s "Meet the Spy". Some would argue whether the Spy is a soft or hard counter to the sniper, although it largely depends on the player's skill and general awareness. 

Hard counters are classes which completely obliterate another class with little to no effort. Spearmen are often given as a hard counter to cavalry charges—although the cavalry could win, it's more than likely not going to happen. The best answer here is to call in some archers.

So are soft counters or hard counters better for your game? Well, obviously it depends on what you're aiming for, but for nearly every game out there the answer is simple: soft counters are better.

The reason for this is simple: hard counters deny counterplay. Having a more difficult game due to a counterpick is fine: being unable to do anything at all is bad. Soft counters can generally be worked around, but hard counters leave no room for creativity or tactical moves.

So can a hard counter ever be acceptable design? Yes, under two scenarios:

  1. The player is able to change class midgame, allowing them to counter the counter.
  2. The player is part of a larger team and is able to “offload” the problem onto someone else.

That's not to say that hard counters are acceptable in these situations, but the problem is less pronounced. The player still has some sort of choice available, and may be able to "avoid" the issue.

Boiling It All Down

So what can we take away from all this? Really, class design isn't all that complicated. It comes down to a single idea:

Let the player play the game in a way that they enjoy.

That's it—the great secret to class design. It doesn't matter what sort of game you're making, all that matters is that the players are having fun. 

The very essence of class design is, as we've said so many times, about choice. It's about the player choosing to play something they enjoy, about being given meaningful choices throughout the game, and about how those choices interact with the challenges they face, be it enemy AI or other players.

And because new games often contain a world of information, it allows players to make choices more meaningful. A new player might be overwhelmed looking at 100 different statistics, but if you give them just a handful of choices—ask them which class they want to play—they can answer that easily. They don't need to worry what the correct number of points to spend on vitality is; they simply pick a class and get stuck in.

Your class gives players additional ways of playing your game, and in a way each class is like making an entirely new game. As long as your class doesn't stop other people having fun, it's probably fine.

And remember, at the end of the day, each game is different. There is no "correct" in game design, and there are no doubt many successful games that break some (or all) of these rules. Just try to consider them when designing your game, and don't be afraid to break the mould and try something different. All of this is aimed at one simple idea: make your game fun.

Unity 2D Tile-Based 'Sokoban' Game

$
0
0
Final product image
What You'll Be Creating

In this tutorial we will be exploring an approach for creating a sokoban or crate-pusher game using tile-based logic and a two-dimensional array to hold level data. We are using Unity for development with C# as the scripting language. Please download the source files provided with this tutorial to follow along.

1. The Sokoban Game

There may be few among us who may not have played a Sokoban game variant. The original version may even be older than some of you. Please check out the wiki page for some details. Essentially, we have a character or user-controlled element which has to push crates or similar elements onto its destination tile. 

The level consists of a square or rectangular grid of tiles where a tile can be a non-walkable one or a walkable one. We can walk on the walkable tiles and push the crates onto them. Special walkable tiles would be marked as destination tiles, which is where the crate should eventually rest in order to complete the level. The character is usually controlled using a keyboard. Once all crates have reached a destination tile, the level is complete.

Tile-based development essentially means that our game is composed of a number of tiles spread in a predetermined way. A level data element will represent how the tiles would need to be spread out to create our level. In our case, we'll be using a square tile-based grid. You can read more on tile-based games here on Envato Tuts+.

2. Preparing the Unity Project

Let's see how we have organised our Unity project for this tutorial.

The Art

For this tutorial project, we are not using any external art assets, but will use the sprite primitives created with the latest Unity version 2017.1. The image below shows how we can create different shaped sprites within Unity.

How to create sprites within United 20171

We will use the Square sprite to represent a single tile in our sokoban level grid. We will use the Triangle sprite to represent our character, and we will use the Circle sprite to represent a crate, or in this case a ball. The normal ground tiles are white, whereas the destination tiles have a different colour to stand out.

The Level Data

We will be representing our level data in the form of a two-dimensional array which provides the perfect correlation between the logic and visual elements. We use a simple text file to store the level data, which makes it easier for us to edit the level outside of Unity or change levels simply by changing the files loaded. The Resources folder has a level text file, which has our default level.

The level has seven columns and five rows. A value of 1 means that we have a ground tile at that position. A value of -1 means that it is a non-walkable tile, whereas a value of 0 means that it is a destination tile. The value 2 represents our hero, and 3 represents a pushable ball. Just by looking at the level data, we can visualise what our level would look like.

3. Creating a Sokoban Game Level

To keep things simple, and as it is not a very complicated logic, we have only a single Sokoban.cs script file for the project, and it's attached to the scene camera. Please keep it open in your editor while you follow the rest of the tutorial.

Special Level Data

The level data represented by the 2D array is not only used to create the initial grid but is also used throughout the game to track level changes and game progress. This means that the current values are not sufficient to represent some of the level states during game play. 

Each value represents the state of the corresponding tile in the level. We need additional values for representing a ball on the destination tile and the hero on the destination tile, which respectively are -3 and -2. These values could be any value that you assign in the game script, not necessarily the same values we have used here. 

Parsing the Level Text File

The first step is to load our level data into a 2D array from the external text file. We use the ParseLevel method to load the string value and split it to populate our levelData 2D array.

While parsing, we determine the number of rows and columns our level has as we populate our levelData.

Drawing Level

Once we have our level data, we can draw our level on the screen. We use the CreateLevel method to do just that.

For our level, we have set a tileSize value of 50, which is the length of the side of one square tile in our level grid. We loop through our 2D array and determine the value stored at each of the i and j indices of the array. If this value is not an invalidTile (-1) then we create a new GameObject named tile. We attach a SpriteRenderer component to tile and assign the corresponding Sprite or Color depending on the value at the array index. 

While placing the hero or the ball, we need to first create a ground tile and then create these tiles. As the hero and ball need to be overlaying the ground tile, we give their SpriteRenderer a higher sortingOrder. All tiles are assigned a localScale of tileSize so they are 50x50 in our scene. 

We keep track of the number of balls in our scene using the ballCount variable, and there should be the same or a higher number of destination tiles in our level to make level completion possible. The magic happens in a single line of code where we determine the position of each tile using the GetScreenPointFromLevelIndices(int row,int col) method.

The world position of a tile is determined by multiplying the level indices with the tileSize value. The middleOffset variable is used to align the level in the middle of the screen. Notice that the row value is multiplied by a negative value in order to support the inverted y axis in Unity.

4. Sokoban Logic

Now that we have displayed our level, let's proceed to the game logic. We need to listen for user key press input and move the hero based on the input. The key press determines a required direction of motion, and the hero needs to be moved in that direction. There are various scenarios to consider once we have determined the required direction of motion. Let's say that the tile next to hero in this direction is tileK.

  • Is there a tile in the scene at that position, or is it outside our grid?
  • Is tileK a walkable tile?
  • Is tileK occupied by a ball?

If the position of tileK is outside the grid, we do no need to do anything. If tileK is valid and is walkable, then we need to move hero to that position and update our levelData array. If tileK has a ball, then we need to consider the next neighbour in the same direction, say tileL.

  • Is tileL outside the grid?
  • Is tileL a walkable tile?
  • Is tileL occupied by a ball?

Only in the case where tileL is a walkable, non-occupied tile should we move the hero and the ball at tileK to tileK and tileL respectively. After successful movement, we need to update the levelData array.

Supporting Functions

The above logic means that we need to know which tile our hero is currently at. We also need to determine if a certain tile has a ball and should have access to that ball. 

To facilitate this, we use a Dictionary called occupants which stores a GameObject as key and its array indices stored as Vector2 as value. In the CreateLevel method, we populate occupants when we create hero or ball. Once we have the dictionary populated, we can use the GetOccupantAtPosition to get back the GameObject at a given array index.

The IsOccupied method determines whether the levelData value at the indices provided represents a ball.

We also need a way to check if a given position is inside our grid and if that tile is walkable. The IsValidPosition method checks the level indices passed in as parameters to determine whether it falls inside our level dimensions. It also checks whether we have an invalidTile as that index in the levelData.

Responding to User Input

In the Update method of our game script, we check for the user KeyUp events and compare against our input keys stored in the userInputKeys array. Once the required direction of motion is determined, we call the TryMoveHero method with the direction as a parameter.

The TryMoveHero method is where our core game logic explained at the start of this section is implemented. Please go through the following method carefully to see how the logic is implemented as explained above.

In order to get the next position along a certain direction based on a provided position, we use the GetNextPositionAlong method. It is just a matter of incrementing or decrementing either of the indices according to the direction.

Before moving hero or ball, we need to clear their currently occupied position in the levelData array. This is done using the RemoveOccupant method.

If we find a heroTile or ballTile at the given index, we need to set it to groundTile. If we find a heroOnDestinationTile or ballOnDestinationTile then we need to set it to destinationTile.

Level Completion

The level is complete when all balls are at their destinations.

A Completed Level

After each successful movement, we call the CheckCompletion method to see if the level is completed. We loop through our levelData array and count the number of ballOnDestinationTile occurrences. If this number is equal to our total number of balls determined by ballCount, the level is complete.

Conclusion

This is a simple and efficient implementation of sokoban logic. You can create your own levels by altering the text file or creating a new one and changing the levelName variable to point to your new text file. 

The current implementation uses the keyboard to control the hero. I would invite you to try and change the control to tap-based so that we can support touch-based devices. This would involve adding some 2D path finding as well if you fancy tapping on any tile to lead the hero there.

There will be a follow-up tutorial where we'll explore how the current project can be used to create isometric and hexagonal versions of sokoban with minimal changes. 

Viewing all 728 articles
Browse latest View live