MrWhimble

Lewis Bonner

Home Projects Blog

Backyard Dungeon Development

Final Run

23/05/2022

Sword Fun

Once the staff worked, I started work on the sword. The sword does damage using a trigger collider which is the same shape as the swipe VFX. Once something enters the trigger, it checks if the point of entry is inside a "sweep angle" and if it is, damage is applied to the object. I found that there were issues with this system, but these could be easily fixed. The primary issue was the swipe causing multiple hits if the object re-entered the trigger. This was easily solved though using a list of gameobjects and checking if the object that entered the trigger has already been hit.

Part of the damage system is the data that can be transfered to the hit object. It contains the object that delt the damage (sup as a projectile), the object that the originally started the attack (the player/enemy), the target (the object that is hit), the position of the attack (useful for VFX spawning and physics), the normal of the attack (for setting the direction of VFX and force), and the damage value. I use these variables for applying forces to the boxing bag in the garden, and they could be used for special weapons such as those with life-steal.

Boxing Box With Hit Debugs

Thanks to how I've built the inventory system, the player and the enemies can both use the same weapons and inventory systems. We wont want the enemies using the exact same weapons because of balancing but the option is there.

Audio Triggers

Audio sources in Unity are good for playing single sounds but when you have multiple clips of the same sound, it's good to have an easy alternative in place. I solved this by creating audio triggers and "sounds" which are scriptable objects with a list of audio clips and some extra settings like min/max pitch.

Sounds Unity Inspector

I made multiple components that all have different funtions. One just plays a sound, one plays multiple sounds, one spawns a new audio source (for objects that are destroyed and need to play a sound), and one for playing a sound globally.

Audio Source Trigger

I enjoyed making icons for the triggers (the audio speaker icon with a lightning bolt) as I would like to use this system in future games as it removes the need to constantly type
audioSource.clip = clips[Random.Range(0, clips.Length)];

Audio Trigger Icons in Editor

Test Day

We hosted an event to test the game before the main release on the 27th (May). It was really fun but it didn't come without it's problems; the animations broke an hour before the event was starting, the temporary portals were spawning in every room, and the skeleton enemies weren't working.

Luckily, all these issues were fixed and the day continued with good review and some bugs for me and the other programmer to fix. Once I got home, I spend a few hours fixing most of the bugs that cropped up and added some extra features that some players recommended.

Git Commit Post-Test Day

A Few More Fixes...

I made a bunch of changes before the submission to get the game into a state where anyone can load it and be able to play. I also fixed some bugs that I didn't have time to do the first commit and added the rest of the sounds to the project.

Git Commit Before Submission

The Little Things

09/05/2022

Custom Swapping Editor

I created a custom editor for the designers to bulk-swap GameObjects in the scene. It replaces any selected GameObjects with the one assigned in the editor window and if the new object is a prefab, a tickbox can be ticked to instantiate as the prefab instance. This is extra useful for objects such as the doors or torches as they can all be changed at once.

Object Swapper Editor

Inventory Assets and Hovering

I added the item icons and implemented the slot icon changing when being hovered over. This was simple as the IPointerEnter and IPointerExit handles were already in the script.

Slot Hovering

Let There be Fire

I started working on the items and their functionality. In a perfect world this would be a custom editor like the effects or the shader graph, but there isn't time for that, so I'll change the idea.

The items now have a Unity event called OnUse, and when the item is used, it is invoked. For the fire staff, I have a projectile instantiating script that fires the fire ball projectile. When the projectile hits anything, it can instantiate another prefab, do damage, and apply effects onto whatever it's hit.

Using the Fire Staff

I will be continuing to work on the other items in the coming weeks.

Moar Inventory

25/04/2022

Moving Items

This week I worked on moving items around the inventory. I made an object called an "inventory grabber" which would be used to interact with the UI. First I needed to know what inventory slot the player is hovering over. I used a static variable and the IPointerEnter and IPointerExit handles to change the static variable. The grabber then used this varaible to determine which slot was being interacted with and run the correct methods accordingly. I also edded item swapping and items currently snap back to their last location.

Moving Items Around Player Slots

Because the item slots are technically handling moveing the items around, the item grabber works between inventories aswell, such as between the player's inventory and a chest's inventory.

Moving Items Around Multiple Inventories

Tooltips

Another programmer in the team made a tooltips system for showing information about the effects and items. I quickly implemented it with very little trouble.

Inventory Tooltips

Blocking Actions

One thing I haven't shown in the gifs is swapping items that are equip. This is because the UI didn't block input actions, and so the items would get used when trying to move items around. I fixed this with a utility method that checks for any UI over the mouse. Another issue was the items to getting equip when placed in the selected slot, but this was fixed.

Inventory Action Blocking

Asset Additions

Now that we had more props in the game, I worked on making some of them more interactable. One example of this is the boxing bag in the garden. The aim of this is for it to act as something for the player to practice hitting before entering the actual gameplay. I just used a basic Unity spring joint at the top of the bag and it worked well.
At the moment, the sword doesn't actually hit the bag, and it moves because of the player stepping forward.

First Look at Boxing Bag

I also implemented the swing VFX made by another member of the team to play whenever the swing animations are played. I had to make another animator script to change the angle of the swing, but everything works well and I should be able to add damage very easily.

New Sword Swipe

Inventory

11/04/2022

Level and Movement

Before I get onto the main subject, The lights now change as the level flips. This is a value defined in the level data.

Lights in Level

The player can also now walk while holding right-click

Player Walking

Time for the main subject.

The Inventory

I started properly working on the inventory the past 2 weeks to get it ready for the items used in the game. After working on the effects system, I wanted the items to share the modularity of the effects so that designing and adding new items would be easy to do. Due to time constrains though, I cut back on these ideas and kept with just seperating most of the function from the visuals/UI.

I already had some scripts that I made earlier, but scrapped them for a better format. The inventory is split up into an Inventory object and an InventoryBehaviour which gameobjects use to acces the inventory. Game entites, such as the player and enemies, use an extended version of the behaviour which contains methods for easily switch inventory slots and using the items.

Items are stored in an array and are MonoBehaviours that parent themselves to the inventory that contains them. This isn't the most elegant solution as it requires every item to have a prefab GameObject but it works well enough for this game.

The UI

The UI is not required for the inventory to function and is very easy to add to a scene when required. It is event driven which works very well until the connected inventory needs to be changed. This can be solved though by just running a loop through the connected inventory slots when required.

Once the UI showed what items were in the inventory, I needed to get the item selection working as well as the item equiping/unequiping. This was pretty simple using a property for the selected slot variable and just running the unequip or equip methods on the selected item before and after the change.

The actual inventory does not know what slot is selected and doesn't need to know as it's just a container for the items with methods to add and remove items (methods which just call other methods in the ItemSlot class)

Changing Slots and Equiping

Finally Levels

28/03/2022

Level Editor

The last 2 weeks have make me realise that the original plan for the level designer was over complex for the amount of time we have to develop the game. I updated the level designer to now use prefabs for the rooms which could then be added to a list in the level data.

I have added some extra UI when editing rooms to make the process easier for me and the designers to make the rooms. The first of these is an easy way to make a base room prefab which has all the important scripts and child GameObjects needed for each room. It is important that the designers understand the basics of how the room works, so I also created a document which serves as a quick guide to the room building.
I reused the old level designer editor for the tile grid, and I added a custom editor which draws arrows to show the direction of doors.

Room in Prefab Scene

Level Generation

The generation of the levels is quite simple and invloves picking a random room from the list and trying to put two of the doors together. This is OK for now mut results in very basic levels with no loops. It also creates the issue of dungeons having different sizes depending on the types of rooms used. This could be fixed with a weighting depending on the generation level, but I having done that in this situation. There is also the issue of the walls and doors being 2 tiles thick, which feels quite clumsy, but programming a new generation method at the time would've taken too long.

Big Level Generated

It does fell nice to finally have a level to walk around in even if it's in the raw form.

Player walking Around Greybox Level

Level Transitions

One of the key points of this game are the tiles flipping when going between the real world and the child's imagination and I'm finally going to get aroudn to doing it.
Mainly due to my lack of shader knowledge, I'm flipping the tiles using their transforms. I would rather use the shader for performance reasons but I can still do some optimations such as not flipping tiles outside of the range of the player.

This was an early GIF I shared with the team, which shows the tile flipping with some issues such as lighting. It is also the first look at the actual art in the game made by the rest of the team.

Early Tile Flipping

Room Player Awareness

Part of my goal for this game is to create systems that dont require each other to work, such as seperating function from UI. This improves test-ability. To continue this, I'm using Unity events whenever the player enters and exits a room, as well as when the level is generated. The doors of a room detect when a player leaves or enteres a room using a trigger collider. This then sends that to the connected room controller, and that sends the action to the level manager which has the unity events on it.

Player Entering Rooms

I used this to create a minimap for the level, which is a seperate script that could theoretically doesnt even need to be controlled by the level manager. I also use the OnRoomEnter and OnRoomExit events to change the colour of the rooms in the minimap as a basic way of showing the player where they are. (Not shown in the screenshot).

Level with Minimap

Levels And Effects

14/03/2022

Level Designer

The plan is for the levels in the game to be procedually generated using pre-build rooms. To make this easier, I created the start of a custom editor called the "Level Designer". This would show a grid in the scene and allow you to select a level and room to edit. Then a designer would be able to paint tiles into the scene, much like a tile map editor.

Level Designer (Old)

After completing this editor and thinking about the time it took, I realised there is a simplar way of making the level editor. I scrapped the level designer (for now) and moved the scripts so they wouldn't be used. I now had a level manager for controlling the level and the generation, and a room controller for dealing with the room and doors, etc. Each room would now be a prefab with specific children for certain types of objects (tiles, walls, props, etc). I added warnings and errors to the room controller inspector for these child objects and some buttons for snapping tiles and walls to the grid. Tiles can be placed quickly with Ctrl + D.

Room Controller Editor 1

I still use the level designer editor window for randomly rotating selected tiles and showing the grid.

Level Designer (Rotation Controls)

Effect Zones

Lots happened with the effects, the main addition being the effect zones. These apply an effect when an entity is within a zone and remove the effect when they leave. This will be useful for effects like lava and ice which don't have durations. While thinking about how the lava acts, I also added a post-effect modifier which applies another effect once it has ended. This created some problems with the order of the modifiers so I finally added some buttons to change the order of them.
The lava effect in the editor looks like this.

Lava Effect Editor

The effect zones are very easy to use. It's made up of two parts: the controller, and the volumes. The volumes are children of the controller and have trigger colliders on them when tells the controller what has entered and left. The controller tracks how many times each object enters and leaves a volume so overlapping doesn't matter.
The only varaible in the inspector is the zone effect which is applied to the objects.

Effect Zone in Inspector Effect Zone in Editor

V-Effects

As the VFX begin to be completed, I created a quick system for spawning in the prefabs for each effect. It's all very temporary at the moment as I want to spend more time making it work with different confiigurations of effects and using the same architecture as the effect UI.

This shows the lava effect turning into the fire effect for 3 seconds with temporary visuals.

Temp Lava VFX

Moar Effects

28/02/2022

Modular Effects

The current system for the effects is OK, but there's an issue... If I wanted an effect that did damage and made the player slide, I would have to inherit from frozen and damage scripts, which I can't do.
To fix this, I changed it to a modifier system. Effects have modifiers that change single parameters. These include speed, health, and movement smoothing modifiers. I Created a custom editor for this to make it easier and cleaner to add modifiers using scriptable objects and Unity's "AddObjectToAsset" method.

Effects Custom Editor (Effect Type) Effects Custom Editor (Modifiers)

This allows creating and editing effects efficiently and easily. Part of the editor involves showing the properties of the modifier scriptable objects. This is done with a script from Tom Kail that extends the scriptable object drawer. I changed some of the private methods to public and could then use them in the editor.
Finally, here's an example of the frozen effect with temporary art.

Frozen Effect in Editor

Edge-case Fixing

So there are situations where when effects end, they can override other effects. This is most obvious when the speed has a speed effect and walks into a stun effect. When the stun effect ends, it resets the speed back to default, cancelling the speed effect. I could fix this by setting the speed of the player every frame, but that sounds like a bad idea that will only make problems worse.
My fix is to have a list of floats inside of the movement script which contains the speed, and then multiply the speed by each value in the list. This covers all cases and means effects like speed up and slow down cancel out to normal speed.

In the Beginning

14/02/2022

Initial Set Up

We start at the beginning.
As a team of 8, we needed to setup a way for everyone to work together on a single Unity project. For this, I created a Git repository on Github. Initial commits just involved adding some folders, added TextMeshPro, and modifying the git ignore file; which should've been the first thing I did.

I created some of the basic scripts that would be needed for some of the main systems. These include the level, inventory, items, and effects scripts.

The Start of Temporary Dev Assets

Because creating assets takes time, I created some of my own assets while I waited. This started with the player character which turned into a Minecraft character. I used Blender and had to rig and make some animations. I also spent some time UV unwrapping the character to work with other skins.
The final product is quite usable until the actual player model is ready.

Dev Player Moving

I also created a diamond sword and bow for test items in the future.

The Player

The player is controlled by a variety of scripts. There's a custom character controller which moves the player by controlling the rigidbody's velocity. There's a movement script which bridges the character controller and player input. And a script is used to rotate the player depending on the target direction or mouse direction.

These are seperate scripts because they do different things. It also means the player and the enemies can use the same character controller and the AI can have its own movement script for sending input. This also means the effects system will be cleaner and wont require as many checks.

The Effects

The effects I started by myself but realized it's probably a better idea to start with a tutorial. I used a tutorial by Jonathan Yu to get a good base on the effects system. This went through a buffable entity, the base effect and data, and an example effect which modifies speed. I expanded on this by adding an immune list for effects the entity is immune to. I also added a bunch of effects including a frozen effect which freezes the player and makes them slide.
At this time, the player can still rotate.

Dev Player Frozen

I also added an effect that changes speed and one that does damage.
The effects also have a UI, which is completely seperate from the effects system. This means the effects have no knowledge of the UI, meaning its not needed for the enemies, for example. It also makes testing much easier as a UI is not required and shouldn't ever be a problem.

The Enemies

I created the start of the enemy's scripts. Many changes were made to existing scripts including the movement script. Before the change, the player script had the speed the character moves. After the change, the speed was moved to a seperate script and the player movement inherited from that script. This meant that the AI could use a custom movement script that also inherited the speed.
Because of this, the effect system would work with the enemies without any changes to the scripts. The side effect of this is that I can't use Unity's Navmesh Agent, which adds a small amount of work, but I don't think as much as making the agent work with something like the movement smoothing.

Here's an example of enemies getting confused (which inverts the speed) and then getting frozen.

Enemies and Effects