Showing posts with label Tree Sprites. Show all posts
Showing posts with label Tree Sprites. Show all posts

Sunday, August 16, 2020

Trees and Context Menus


Recently, I was working on the right click context menu for trees and realized I needed to do something different.  Up to that point I had two colliders on the tree objects.  The first was a Capsule Collider 2D.  This game component allows collision detection between it and the Rigidbody 2D component that sits on the player object.  When they touch an event is fired which allows me to change the tree sprite's alpha or transparency channel from solid to something almost invisible.  You can see the effect here.

Tree Fade

You can imagine how important tree fading is going to be when the player is stuck in a thick forest trying to avoid hostile animals, or in a swamp trying to make sure not to step on a quicksand tile hidden beneath some moss.

The second collider was a simple box collider positioned on the bottom portion of the tree.  This collider was used by the physics engine to perform a raycast2D hit check from the point on the screen where the mouse right click event fired down to the tree's box collider.  If the collider hit was a box collider and the object's tag was "tree" I knew a tree had been right clicked and I needed to show the tree menu, which currently looks like this.

Tree Context Menu

This was working fine except for two things.  First, the orange square you see in the image above indicates the selected tile.  It hops from tile to tile following the mouse as it moves across the scene.  However, it did not exist when I was using the box collider.  Instead, I had a mouse pointer that resembled a target.  The second issue had to do with lining up that little mouse pointer just right so the player could select the tree and right click the invisible box collider hoping to score a hit to open the menu.  No, this was not my idea of a mini-game.  It was down right annoying!  Over half the time I missed the collider altogether.  There was a third issue that could be argued as being more important than the previous two.  Physics collision is expensive!  In fact, the more complex the collider type is, the more resources are required by the physics engine to calculate a hit.  This is why I chose a capsule collider instead of a polygon or edge collider for the tree fade check.  Getting back to the task at hand, something had to change.

This got me thinking about the nature of this game and what tools I had to tackle this problem.  Being a tile-based 2D game, I could rely on a few data structures I manage in memory.  Every tree has a corresponding tilemap tile it sits above.  Every tile space is limited to just one tree object.  The tilemap object has built-in methods to get a specific tile based on capturing a screen point (i.e. the mouse click spot) and translating it to a cell on the tilemap.  What made this so great was that I could remove the box collider from the tree prefab, which improves performance!

The new approach looks like this.  In my PlayerMovement.cs class I capture the right mouse click event. I get the click's world position and translate it to a tilemap grid position.  I then get the player's position which is stored in a singleton class.  Singleton classes are classes in C# that can only be instantiated once during the lifetime of the instance.  Once you instantiate them, you call class.Instance() to access them.  I limit interaction with the world to a few tiles around the player.  It wouldn't make sense to chop a tree that was 10 tiles away!

Once it is determined that the player is close enough to the target to perform the action, I needed to check a few data structures to understand what is beneath the mouse click.  I already mentioned there can only be one tree per tile.  But the tile may not have a tree.  It might be an animal, another plant, or a log cabin!  The order of checks then has to be to check for any game object on top of the tile.  Then, if not found check for the top portion of the tile (grass, etc.).  If that doesn't exist, the third and final option is the tile's core.  This allows me to "know" what exists at that position on the tilemap.  From there, it is just a matter of turning on the correct menu and positioning it where I want it to appear.

This refactoring of the code took a few hours but it was totally worth it.  It saved precious physics calculations.  Also, this new method of locating trees is more intuitive for the player.  As long as the user has a visual aid to selecting the desired tile, the player will be able to interact with every game object in a way that feels second-nature.  Check out the video below for a look at the context menu in action.  Until next time...




Saturday, August 15, 2020

The Evolution of Trees

When I started on the web game, I had envisioned trees as being something akin to a tile type.  By that, I mean the trees would be the same size as the tile they occupied.  Here is a screenshot from the web game to show a few types like maple, oak, pine and fir.

Early Trees from the Web Game

When I decided to abandon that project, I also abandoned the idea of everything in the game being limited to a single tile space.  This led me to searching for trees that were larger than a tile and more detailed.  I was surprised to find so many free basic tree images on the internet.  Some were a bit too simple and others were a bit too generic.  I wanted the player to be able to look at a tree and know what kind it was.  Unfortunately, tree images are so prolific on the web that you can find just about the same generic image labeled as a dozen types of trees, none of which are actually represented by the image.    Here are a few decent samples I was able to find.

Early Tree Sources

The trees didn't look bad, but they really didn't feel like the kind of trees I wanted in the Unity game.  Speaking of Unity, there are many great 3D tree assets on the Unity Store, but I am not building a 3D game.  I wanted flat 2D trees that would be pretty easy to identify or at least close enough to the actual species that the player would learn to recognize them.  Another idea I had was to have sprite sheets showing age variations for each tree type.  Here are the cherry and cedar tree sprite sheets.


The more savvy reader might recognize the cedar sprites.  They are from a popular free art asset package prolifically distributed on the web.  I merely resized them and touched up the colors.  I suppose I would have stayed with these sprite sheets were it not for my obsession to detail.  No, these were just not genuine enough for me.  I wanted trees that would stand out and provide a real sense of immersion.  I wanted the player to feel like they were surviving in a real forest.  Then the idea came to me.  What if I could use real tree images within a 2D pixel game?  The idea was just crazy enough for me to want to try it out.  I began looking around the web for free public tree pictures.  They didn't have to be standalone images.  They just had to be public domain and good enough to edit.  Fortunately, I found some excellent source images and proceeded to clean them up for use in the game.  The result was exactly what I was after.  Take a look at two of the trees found in Survive and Thrive.

The Pine and Aspen Trees

And here is an in-game screenshot of the Aspen after adding some additional shading.

Survive And Thrive
Standing Under the Aspen Tree

By using real images as a foundation, I hope to create a look and feel that is very much wilderness in the minds of the player, but still a fun 2D world.  Taking this path was certainly not the easiest.  I spent many hours on each tree, working each pixel cleaning them up and modifying areas that did not look like I wanted.  Some required more work than others.  I believe only one tree has survived in the game that wasn't taken from a real photo.  It was actually a vector image of the type of tree I was looking for.  To date, I have still not found a real image of that tree.  Perhaps I will not find it, but the vector tree serves the purpose for now.  Until next time.