This was my attempt to create a Rust-like inventory system that would be adaptable and applicable to many different use cases. You can see the code behind this system here, as well as a more in depth breakdown of the specifics. In it's current form, it is very focused on coins, but the way it was built makes creating new "pickupable" items quite simple. The player's inventory, as well as the storage devices, both use the same script. This script dynamically creates a grid inventory system in a 2D array based on the dimensions given by the user in the game window. There is also the option to have these inventories start out with a predetermined amount of any given item, meaning it can also be used to deliver items to the player. When you pick up a new item, this system checks to first see if there is even space for this item. It then checks if any stacks of that item exist in your inventory and if those stacks have room for one more. If not, it simply creates a new slot and a new count of that item. If a stack does already exist, it will stack with it up to that item's max stack amount. If the items you picked up exceed the items max stack amount, a new stack will be created. In the case that you do not have room for the item, it will simply drop back onto the ground.
Once the item is stored in your inventory, it can be manipulated in a variety of ways. You can click and drag that item into different inventory slots, as well as inventory slots in other inventories, if you have the UI for them open. You can also drag and drop items on top of each other, which will trigger one of a few possibilities. If they are the same type of item, they will stack up to their max stack size, and create a new stack in the case the max stack size is exceeded. If they are different types of items, these two items will swap positions in the grid. You also have the ability to drop these items back onto the ground from within the menu. If you right click the item, it will drop one on the ground. You can also click and hold to drop the entire stack. Alternatively, you can click and drag the stack out of your inventory screen and drop it outside its bounds to drop the entire stack. You can also manipulate the items using tools like the recycler, which will take whatever item you give it and reduce it to its core components. What components each item breaks into as well as whether or not it is even recyclable is defined by a script placed on the object. This can be expanded to allow for a multitude of variations. All in all, I ended up very proud of this system and fully plan to use it in projects going forward, and I expect to find many, many bugs with it and improve it over time.
This system was designed to allow me to have roaming NPC's with traits assigned to them that affect their behavior in some way. Code viewable here. This was meant as a general AI practice but also a proof of concept for a future idea. Essentially within the scope of this project as it stands AI will be randomly spawned around the level based on spawn points set in editor. These AI will be assigned traits like attractive, scary, runner, brave, and chaser. Each one will decide how this AI interacts with other AI. These AI will roam around, acting within their expected traits until their randomly assigned "lifespan" parameter runs out, at which point they will select a random spawn point to walk back to and de-spawn. Following that, a new AI will spawn with a new set of traits and do the same. This hopefully ensures that the AI you see roaming around will always seem fresh and interesting. As far as the traits go, attractive AI will attract others towards them, runners will run away from any AI that gets near them, scary AI will force every nearby AI to run away, brave AI will be unaffected by scary AI, and chasers will run after the nearest AI to them. These are somewhat arbitrary traits, but I plan to use these to build roaming NPC's that will react to the player and their actions in various ways, and I figured these traits give the AI some unique ways to react. When an AI is scared and running away from something, I use the system outlined below, which describes my method for making an AI intelligently run away from something.
A scary AI
An attractive AI
An AI surrounded by scary chasers
AI with no traits, roaming.
This was a system I never expected to be complicated, but regardless it ended up taking me weeks of iterations before I got it in a place I liked. On the surface it does seem really simple, making an AI run away from something. Just turn it to face away from the thing it is running from then make it move forward, solved. The problems arise when that AI runs into a wall, or an obstacle, or anything really. The logic of making it run away from a target while also making it avoid obstacles is where it got complicated. My technique ended up being possibly overengineered, but effective. You can see the code here. Essentially I have a raycast go out from in front of the AI while they are scared. If that raycast hits something, it reflects off it at a random angle within a given range, then shoots another raycast. If that raycast doesn't hit anything, the AI navigates to that point. If it does hit something, it reflects again. This is repeated multiple times until a cutoff point is reached, wherein the raycast has reflected too many times and the AI is just told to run in a random direction to hopefully get them out of whatever complicated geometry they have found themselves in. This results in the appearance of a person noticing a wall is coming and turning to avoid it, although the logic will still occasionally get stuck leading to a scared AI hugging a wall and getting caught. Nevertheless I think it performs well for my purposes.
A breakdown of the concept I made to help myself visualize the process, This is one of many similar sketches I did before I settled on a concept that worked.
This system was meant to allow me to do facial animations via sprite swapping without the Unity Animation system. Essentially I have these large sprite sheets with different face drawings that I have the code swap between. It does this by changing the UV's of the face mesh, which is separated from the rest of the body. I have methods that force certain expressions, as well as passive methods that run in the background regardless of the expression that control things like blinking. Characters with this script will passively blink and idly look from side to side and hold whatever expression state they are currently in. Here's the code.
An example of a sprite sheet as of right now. Each colored block is meant to represent a different emotion.
This was an AI I made for some practice but I may end up having a version of it in a future project. It is pretty basic, but I learned a lot and am still really satisfied with the result. Basically the Roombas are just little robots that navigate around the level tracking down and picking up trash objects. It doesn't behave like a real Roomba, as this one detects the nearest trash and targets it. I have a "TrashItem" component on the items that allows me to mark them as trash and specify what type of trash. The Roombas have internal storage that can cap out, at which point they would just dump their contents into a trash bin. As it currently stands though they just dump their contents on the ground, albeit sorted out in large bins. This practice as well as some of the specific techniques here would go on to be very important in future AI projects, such as the method for searching and finding the nearest of something from a long list of things. Here's the code.
The Roombas at work in an excessive configuration. Ideally, in a real setup, there would be very few Roombas. But, I wanted to push the system. You can see them pick up trash items until they reach their capacity, then return to dump the trash in their designated place.
Here you can see them wait in line if too many Roombas are currently dumping, but in an ideal setup this would be uncommon.
Concept art / Design
This mechanic was a necessity for the central concept of "The Bomb Level" in "Swallowed Holl". The general idea was a very fragile bomb that would explode if dropped or attacked in any way, and would also explode in the case that the player "World Shifted" while holding the bomb. This meant the player had to navigate through the level while managing to not destroy the bomb. If the player reaches the end of the level with the bomb intact, they win. We also had bomb dispensers that would allow the player to create a new bomb in the case that their last one was destroyed or lost.
The bomb needed to fire a method every time it detected a collision. If the bomb's speed was over a certain threshold on impact, the bomb triggered its "explode" method. This method is actually a variation on the "Breakable Props" system described below, and you can see the code breakdown there. This explosion would break nearby breakable objects which allowed the player to use the bomb as a tool to unlock certain areas. The "explode" method would also be called in the case that the player was holding the bomb and initiated a "world shift". I think overall the bomb's detection of what is and is not a "lethal" impact was far to inconsistent, there were plenty of points where the bomb hit the ground really fast and it would simply bounce off the ground, so that needs some more refining for sure. The bomb dispensers were generally pretty straight forward, when interacted with, they explode all existing bombs on the level, then spawn a new one. They spawned on a small conveyor belt that made it easy to grab for the player.
This was a more general mechanic that I knew needed to be set up for future projects. It was essentially just a reason to learn Unity's event system and set myself up in the future when I want a button or switch to activate a method. So far I have used this system consistently and have found it very helpful. It is overall very straight forward, slap in on an object, tie it to a method on that object, call that method when the event is called. I have used this for the Bomb dispensers, conveyor belts, light switches, doors, debugging, and more. The doors have multiple modes to allow for doors that slide up or down, have custom sound effects, and have the option to be one time use doors, meaning they open once and stay open, or closable.
This was an essential mechanic in "Swallowed Holl". The basic idea is that the player can shift between two parallel versions of their world, the real world and Holl. These two worlds would be structurally very similar, but aesthetically very different. This allows interesting puzzle solving, platforming, and exploration. This mechanic went through a lot of iteration and revisions as it was produced under a very lenient time restraint, and I am very proud of where it ended up. You can see the code here. The method I decided on was having the two versions of the map sitting side by side in unity. I could then calculate the exact distance apart the two worlds were and feed that to the script for each individual level. On button press, the script instantly moves the player the distance between the two maps in the direction of the parallel map. On repeat button press it would do the same operation with negative values, resulting in the shift happening in reverse direction. This way from the players perspective the world around them changed instantly.
Some problems arose from this method though, such as phasing inside of an object that was there in one world but not in the other, or clipping outside the map when one version of the map has a section that does not exist in the other. To fix these issues, I reworked the way I approached this mechanic. Instead of simply moving the player on button press, I had a "dummy" collider in the mirror world, replicating the player's movement. On button press, the player would trade positions with this dummy. If the dummy is colliding with an object, the player will be unable to shift. To make it a bit smarter, I gave the dummy 5 sub-dummies, one in front, one in back, on on either side and one above. They all follow the main dummy and check if they are colliding with anything. If the main dummy is colliding with something, a process begins checking if the sub dummies are "safe". So in the case that the main dummy is colliding with an object and the player shifts, they simply trade places with one of the available safe dummies. There is also a check if the object the dummy is colliding with is considered "breakable". If it is, the script simply breaks the object then shifts the player in that position. In the case that all 6 of the colliders are not considered safe, the player simply cannot shift.
Another wrinkle to this mechanic was the addition of "No-shift Zones". These were simple volumes that removed the player's ability to shift at all. This allowed for a bit more asymmetry with the level design, as I could create sections of the level that do not exist in the mirror world. I could also limit the abilities of the player to make them think and act certain ways. Overall The No-shift Zones could be implemented a lot better, but they generally get the job done.
Early implementation of the idea, here you can see an example of the clipping issue solved above.
This was my first real attempt at making an enemy AI. This persistent boss character was inspired by characters like Mr. X in Resident Evil 2 Remake. The idea was that he would stalk you throughout your time trick or treating in "Dark Cowboy". I took a much more simple and direct approach as compared to Mr. X, as the Dark Cowboy simply chases you and shoots at you. The nuances are more in his phases and behavior. While he is always chasing the player once he is activated, There are certain safe zones you can use to get a break from him. He refuses to enter the houses or yards of houses in the area. His behavior is also influenced by how much trick or treating you have already done. Trick or Treating advances him through his different phases, until he gets to his final phase where you can do little to hide from him.
In his first phase he simply navigates toward the player until he is within a certain distance and he has a direct line of sight to the player. At this point he enters his "draw" phase, where he stances up facing the player and telegraphs an upcoming attack. After a short period of time, the cowboy locks in a rotation towards the player, waits, then fires a bullet straight in front of him. This bullet should be relatively easy for the player to avoid, since there is a bit of time between him locking onto the player and firing that leaves time for the player to dodge. In his second phase, the build up is the same, he simply gives the player a much shorter window in which to dodge. His third phase gives him the ability to actually aim directly at the player as opposed to just firing directly in front of him, meaning the player must now take cover instead of just dodging. And in his fourth and final phase, his draw time is increased as well as introducing the ability to fan the hammer, where he locks onto the player and fires 7 shots directly at them. He can also be temporarily stunned and forced to retreat when attacked by the player. You can see the specifics of the code here.
The cowboy squaring up
Phase one, low accuracy, low draw speed
Phase two, low accuracy, high draw speed
Phase three, high accuracy, high draw speed
Phase four, high accuracy, high draw speed, Fan the hammer
This was a project that I made initially for practice only, but it quickly ended up being one of the core mechanics in my game "Swallowed Holl". It was initially created during a jam stream, seen here, but I have since expanded it quite a lot to make it more usable. It's pretty straight forward and just pushes any object it collides with along it's path. Physics objects as well as players will just slide along at a fixed, configurable pace. The belt can be stopped, sped up, slowed down, or reversed on the fly, and the sliding texture will follow suit. I also have a handful of prefabs of various sizes and orientations to make setting them up in levels more simple. Here you can see a breakdown of the specifics.
Some early versions of the system
"Hunger Dive" was an idea for a movement mechanic specific to Swallowed Holl. Essentially the idea is that by crouching and then jumping, the player would dive forward, mouth agape. Any food items you collide with while in this state would cause you to jump again while automatically eating the food item. This was intended to allow for some platforming as well as some puzzling, using food to cover large gaps or placing food in strategic spots to ensure you could make a large jump. This idea did not get pushed to it's furthest extent within Swallowed Holl, but I absolutely think this simple little dive jump has potential outside of just this one idea. The implementation was done by making some modifications to my movement script
Here it is being used in tandem with the "World Shift" mechanic described above.
Here is a simple example.
This was an attempt to recreate the breakable props system in Deus Ex and games like it, with props having a configurable HP as well levels of brightness on the textures to reflect that HP. In order to get that working I had to create a few scripts, prefabs, and models. You can see the scripts here. First I made the "break", that meaning the shards of the object flying outwards. For this, I had to make shattered versions of every object I wanted to make breakable. I used the Blender boolean modifier to take chunks out of these objects and give them jagged edges. I then made them a prefab with the "Explode.cs" and "Die.cs" scripts. This makes it so that when an object breaks, it deletes the prop, then spawns in this shard prefab that then applies an explosive force to the shards to give the break some impact. The Die.cs script then despawns the shards after a given range of time. This same setup can be used to create a bomb, by configuring a few values. If a breakable prop is set as an explosive, it's explosive force will be applied to nearby objects as well as the shards, and it will also trigger other explosive objects. This also allows the option to add sound and particle effects to really sell the bomb effect. I do think this could be modified to be more performant, for example disabling collision between the shards themselves, and having a maximum allowed amount of shards visible on screen at once configurable by the player.
Shattered version of a guitar modeled by Conor.
This system was just an attempt to make a fun side minigame for the player. It appears in both Dark Cowboy and Swallowed Holl. The goal is pretty self explanatory, make a basketball and a hoop that would recognize when the player made a shot and respond accordingly. There were some complications with keeping it fair, as the player could simply hold the ball and shove it through the hoop, or throw it up from the bottom, or the ball could just barely touch the trigger, then bounce out. It was created in Unity and C#
Here you can see the two triggers necessary to verify a legitimate shot as well as the colliders set up to make shots bouncing off the rim work a bit more in the player's favor.
In an attempt to solve this issue I came up with the idea of having two triggers, one on the top and one on the bottom of the net. Then, the ball would need to pass through the top one, then the bottom one fairly quickly to be counted as a point. I also made it so that if the ball is being held by the player, it will not be considered for a point. This made the system more fair and fun. You can see a breakdown of all the scripts at work here.
This system was an inevitability when setting up a first person character with physics objects lying around. There were a lot of choices for how to go about building it, and from where to draw inspiration. We decided on using a system where the character is visibly holding the object, since the first person hands were already quite silly to begin with. Essentially, the object's collision is turned off and it is made a child of the hands, and then when you drop the item the collision is turned back on and the hand's hierarchy is restored. Some problems did arise from this setup though.
For example, since the object's collision was turned off, it became possible to drop objects through walls or clipping into impossible positions. A quick fix here was to implement a simply box collider in the characters hands that toggles on once an object is held, thereby representing the object having collision while keeping that collision simple. There was also the issue of large objects completely obscuring your view. Furthermore, my quick fix from before felt off when holding objects of varying sizes, as this generic box collider would often not match up with the object's size at all. To solve these I set up an object tagging system that allows you to tag objects as tiny, small, medium, or large. According to this choice, how far away the object is held from the camera changes. This also effects the size of the collider that is enabled when an object is picked up. While this system could be built in a more dynamic way, I think for the range of objects the player is currently able to pick up it works fine. Ideally I would like to add a transparent texture that is applied to the object while holding it to further increase visibility.
On top of that, the player can also throw these objects instead of simply dropping them. A simple force is applied in an upward arc in front of the player if you just tap the throw button, but if the player holds the throw button, it charges up the throw. Once the throw reaches max charge, after about a second, the throw switches to being a straight throw right in front of the player. This allows for a bit more interactivity when it comes to throwing objects for the player. I think giving the player the option to choose a throw style independent of the throw intensity would be another good step in that direction. Ideally the force applied to the objects would be more dependent on the mass of the objects to get more universal throw results, some objects fly away far too quickly when thrown. A predictive arc to show the player where the throw will end up would also be very nice.
Here is the system in action throwing around a few random props in the game "Swallowed Holl".
A simple demonstration from an early version before the animations or the more complicated throw logic were added.
This is the base movement system I have used for Swallowed Holl, MECHROIDVANIA, and Dark Cowboy, and I plan to use it in a lot of projects going forward. It was created following Catlikecoding's movement tutorial, and has been heavily modified from there. Here is the link to the code as it currently stands. I livestreamed our full process of learning this movement system so that I can always go back to that starting point if I need to refresh my understanding of a certain method. Here's a playlist of those streams. This system is very in depth and complicated, and Jasper at Catlikecoding does a far better job explaining the ins and outs than I ever could, so I will just document it's use. In its current form you can walk, run, jump, customize the amount of air jumps you have, wall jump, climb, swim, crouch, and dive.
After being inspired to try and learn how to make custom content for Garry's mod, I spent some time learning the ins and outs of GLUA, a variant of LUA more focused on gaming that Garry's Mod uses, and Hammer, a level editor for the Source Engine. We made a few mods, from custom models imported into the game, custom levels, scripting around those levels, and more like this crowd entity. The idea was simple, I just wanted an entity I could use to fill a crowd and have them give certain reactions based on chat commands. This was a part of a planned Garry's Mod gameshow that we have not moved forward with, but the idea was we would use this artificial crowd to respond live to contestant's actions in a way that would make it all feel more alive. So we set up a makeshift sound stage and recorded various voice lines with a variety of my friends and some loose direction. The scripting was overall not too difficult, I just had to create lists of all the sound effects categorized by their type, like laughing, cheering, mumbling, etc, and do the same for some animations I picked out of the default citizen set that I felt conveyed certain emotions, and then just set up a method that calls a random selection from that list, waits for the duration of the sound effect or animation to end, and then draw again. I also had to set up the logic for the game to recognize these text commands and call the given methods accordingly. Overall pretty easy, and it taught me a good deal about Garry's Mod content creation as well as being very funny in my opinion. A variation on this system and the sound effects were used in Unity for Dark Cowboy, and I will certainly use this idea again in a more polished way as these voicelines are too funny too waste. You can see the full script here. Here's a video of us messing around with the idea a bit later.
This was another program created for use in Wippy Smash. This was a minigame meant to replicate the ball drop game. This one took more effort than the scoreboard for sure, as it involved 3D modeling, physics, and hit detection. This was before I understood how to 3D model, so I requested help from Conor for that part. This was made in Unreal Engine, using the blueprint system. I got the physics of the ball down, giving it just the right amount of bounce, set up the platform to spin, tweaked the colliders to make the game feel more consistent, came up with ideas to place on the holes that fit with Wippy Smash, set up triggers so that the game knows which hole the ball was dropped through, built a UI to show which hole was earned, set up lighting and the secondary cameras for clarity, and polished out bugs. It is still far from perfect, but it was in a good enough shape that I felt comfortable using it as part of a competitive gameshow. This project taught me a lot about working with custom models and colliders, custom physics, triggers, and UI. Seeing all the contestants reactions to it as well as seeing it hold up under the scrutiny of a gameshow gave me a lot of confidence to make more projects like it.
This was one of my early works in Unreal that really taught me a lot about using the blueprint system as well as creating UI. The basis was a scoreboard to work alongside Wippy Smash, a gameshow / card game hybrid. The scoreboard would track 6 players and their overall scores. We automated as much of the process as possible, but someone still needed to be there for transactions of currency. Every player had a panel tracking their name, Wippy, Bibby, Drippy, wins, and losses. Each of these panels could be manually edited via directly typing in a value, or incrementing / decrementing with plus and minus buttons.
A screengrab of the scoreboard in action in Wippy Smash Episode 3
Many of these values, such as Wippy, wins, and losses were determined based on that player's placement, so each round the scoreboard operator would tag each player's placement and then press the "calculate" button, which would assign those values accordingly automatically. There was also an option to edit the amount that the plus and minus buttons add or subtract per panel. Overall quite basic, but it was a stepping stone to me learning more about Unreal as well as being an example of me applying my knowledge of Unreal to solve problems in a creative way.