The Big Endgame: Final Game Dev Update and Summer Recap

It’s been a little over 9 weeks since I started work on my Tree Survival game, and am very pleased to finally have a polished, playable build completed! Please see the video attached below to hear about the entire game and see it in action.

To pick up from last weeks post, I will quickly describe how I achieved the finals goals I outlined for myself from last week:

  • Change monster prefab and add animation system (current prefab has no animations for me to work with):
    • To my surprise, I completely missed that the monster model I was working with already had animations included with it! As a result, I didn’t have to switch models and just continued using the prefab I had in the game. From there, I used Unity’s Mecanim Animation Tool. This tool allowed me to create state machines which switch between different animations. You can find a picture of the state machine I created below. When a monster initially spawns, it begins in a falling state which loops until it hits the ground. Once it hits the ground, a script sets the “Landed” parameter to true, which allows the monster to transition into the landing animation. This landing animation plays once and then enters the walk forward animation, where the “Walking” parameter is set to true. From there, when a monster collides with a tree that the player is on, “Attack1,” Attack2,”and  “Attack3” are selected at random to transition into. This is done by setting the selected attack parameter to true, and the “Walking” parameter to false. If one of these trees are destroyed or a player leaves the tree while the monsters are attacking, a general purpose method sets all attack parameters to false and “Walking” to true, and the monster begins the walking animation again. The hit animation is manually played whenever it is hit, and the monster transitions back into whatever animation state it previously was in. Lastly, the die animation is triggered manually when the monster’s health reaches zero, and upon completion of the death animation, an animation event is triggered which destroys the monster from the game environment.

  • Path monster directly to tree when approaching you:
    • In the FixedUpdate method of the MonsterNavigation script, I grab the GroundMonsterHealthDamage attached to our monster and check to see if it is preparing to attack a tree the player is on. If it is, the monster’s nav mesh agent destination (the component responsible for moving the monster) is set the tree’s position. Otherwise, the destination is set to chase the player. Unfortunately, this adjustment didn’t make the monster’s attack animations and positions always hit the tree (for instance, sometimes a monster may be attacking perpendicular to the tree instead of head on), but it did improve it slightly from when it only tracked the player.
  • Add sound effects to the game:
    • Bullet sound effects
    • Monster sound effects
    • Song (if time allows)
      • These were all fairly simple to implement. The monster model came with sound affects, so I added hit/grunt sound effects to play when the monster is shot (note that I added a 50% chance that a hit would cause a grunt noise to reduce spamming of the audio clip), along with a death noise upon the monster losing all its health. I also found a Creative Commons Licensed gun sound effect from a website called freesound.org, which is played upon each trigger pull where a bullet fires. Implementing these sounds were fairly straightforward. I attached an Audio Source component on each game object which would generate sounds, and then modified my scripts to have public instance AudioClip variables where I could manually assign audio clips in Unity’s GUI. In the script, I grabbed references to the Audio Source component and used the PlayOneShot() method to trigger the desired sound effect. Playing the music was slightly different – I attached an Audio Source to the player component, and on that component I attached another royalty free song titled “Exit the Premises“. From there, I only needed to trigger the Play() method on the Audio Source component to play the song once the player picks up the bow and arrow.

Well, that wraps up the entirety of the “Tree Survival” game that has been months in the making! Also, I happy to report that I completed my Udemy course by covering two final sections: one discussing creating cutscenes, and the other discussing Unity’s lighting effects.

While it might be somewhat cliche, I think that this project wouldn’t be complete unless I reflected on some of the big things I learned this summer.

So….

What Did I Learn?

  • Bugs: they will happen, but don’t let them discourage you.
    • This isn’t necessarily a “game development” only issue, but throughout this entire project, very rarely did I not get tripped up with bugs during development. Nothing is more frustrating than spending three to four hours going through code and component properties to eliminate strange bugs, no matter how simple your implementation is. One thing that stuck in my mind as particularly challenging involved restarting my game. I spent three evenings after work trying to figure out why my bow and arrow was breaking upon reloading the game, only to realize that static variables do not reset upon reloading the game! What was about a six line code addition to my project ended up breaking the entire game, and something that I thought would take at most thirty minutes to implement was taking me three extra days to complete, at a time where I was already behind on development! This was incredibly disheartening, but it’s one of those lessons that teaches you to be prepared for random roadblocks and setbacks, even where you least expect them.
  • Game Development takes much longer than I thought it would:
    • When I set out to make “Tree Survival,” I had much more in mind for how the game would work, with three different enemy types, the ability for enemies to attack the player directly off the tree (back when you could teleport directly to any part of the tree), etc. I was way too ambitious, however, as I made a lot of my timeline plans before I started work, and as a result, I severely overestimated what goals I would be able to achieve. This taught me to constantly re-evaluate goals and to remain focused even when I got discouraged from each deadline miss. I remembered when I was doing preliminary research on game development and came across this video by Extra Credits, which recommended that your first game should take no longer than a month to complete. They immediately followed up by saying that it would take more than a month to complete, which I found somewhat humorous as this perfectly described my game development situation.
  • Discipline is an important factor to Game Development:
    • I remember in mid-July feeling really burnt out on game development – I had been working full time for a month doing software development during the day, and was struggling to find the motivation to do more development after work as a result. Despite this feeling, I always made an effort to still stay focused on Game Development; whether it was tackling little bits of the many features I needed to add to my “Tree Survival” game, or by focusing my energy on going through lectures in my Unity Game Development course. As a result, there were no weeks where I was not working in some capacity on my project this summer. Even though at times it wasn’t fun and I didn’t have any major motivation driving me, discipline got me through those little dry spells. Eventually as I started hitting bigger landmarks (finishing my prototype and nearing a playable game), I would get motivated again to work hard.
  • Getting things working is incredibly satisfying:
    • Whenever I would hit a goal and see it actually working after hours and hours of bashing my head against a problem, nothing feels more incredible than seeing that work pay off into something tangible. It doesn’t have to be anything big like completing your game – simple things like getting my weapon switching and firing mechanics working brought me great joy and satisfaction.

Anyway, I’d like to thank you for checking out my blog! Whether you only glanced at a few posts or read through the whole thing, I appreciate the time taken out of your day to look through it, and I hope that I may have even inspired you to give game development a shot!

Speeding Towards the End

I forgot how productive I am when I’m not balancing game development with an internship, as I easily went beyond the deadlines I set and found myself steadily nearing the end of my project!

To keep this post sort and sweet (mostly for time management reasons), I will be quickly going through the modifications I made to my project for each of the remaining tasks at a higher level and more concise level than on my previous posts.

Gameplay Mechanics:

  • Move teleportation location to the top of pillar and teleport player there
    • I implemented this by adding a transform to the top of the tree as a teleportation spot. Now, instead of flinging the player from one side of the map to the point that the arrow contacts, they are instead instantly teleported to the top of the tree the arrow lands on using the newly created transform.
  • Improve endgame scenario so player can view total kills before restarting the game
    • When the player hits the ground, all enemies are immediately destroyed. This is done by using a public static boolean called “endgameTriggered” in a class titled EndGameDetection. When the player hits the ground, the class “GroundMonsterHealthDamage” attached to every monster object will check if this value is true, and will delete the monster without increasing the total monster kill count for the player.

Aesthetic changes

  • Change spawning location to an elevated platform that destroys once the player leaves it/after 10 seconds elapses
    • Player now starts on an elevated platform, and now when the player grabs the bow, a timer begins and a new element appears on their UI telling them they have 10 seconds to leave the platform. If they leave, the UI warning is disabled and the platform is destroyed. If time runs out while they are still on the platform, physics is activated on the player, and they fall to the ground and trigger an endgame scenario.
  • Change object coloring to make things stand out more (for example, it’s hard to make out the difference between the bullets and the floor)
    • Added different wood textures to the starting platform and trees, and also used a seamless lava texture (see photo below).
      • Since this is an educational project and I have no intention of marketing this game, I grabbed the textures from a quick image search.
    • I increased the size of the bullets by a factor of 3, making them much more noticeable as they fire from the gun.
    • Updated the UI with white text to contrast the darker textures

Aesthetic changes

  • Add rumble to controllers for weapon switching and weapon firing
    • I added a noticeable vibration when the user is ready to switch weapons, and a stronger and longer vibration when they squeeze the grips.
    • There is a vibration at every trigger pull when the user fires their gun.
      • I used the method TriggerHapticPulse, which was provided through SteamVR’s controller components. I modified some of the examples provided in this thread to help me achieve my goals.

The rest of my time went towards my Udemy course. I’m actually really pleased to report that I not only finished the section I wanted to complete 75% of, but I completed another section as well! This is surprising as the last section I did, a Ninja zombie fighting game, actually had 10 and a half hours of lecture content to follow along with. I was able to complete the following section as well, as it was a very simple game with only about 2 hours of lectures. I only have two more sections to complete, and each section is less than 1 hour in lecture content, so I should have no problem getting the course completed before going back to school.

Final Deadlines:

  • Game Development Goals:
    • Change monster prefab and add animation system (current prefab has no animations for me to work with) – 8/16
    • Path monster directly to tree when approaching you – 8/17
    • Add sound effects to the game – 8/17
      • Bullet sound effects
      • Monster sound effects
      • Song (if time allows)
  • Course Goals:
    • Finish last two sections – 8/17

 

Prototype Completed!

I’m happy to report that my game prototype has finally been completed! The only thing I needed to implement from last week was a UI that displayed the health of the tree and total monsters killed. This was actually much more straightforward to setup than I had expected. Using this tutorial as the foundation of my implementation, I added a canvas element onto the VRcamera that was attached to the player game object, and set the canvas’s render mode to world space. From there, I added two text elements for the tree health and total monsters destroyed. To update the tree health, I attached a script to the player object that updates the tree health UI based on the tree the player is touching. If the player is not attached to the tree, the health UI is disabled. The implementation for the monster spawning system is simpler: a public static integer in the TerrainGenerator script keeps track of the monsters killed, and a separate script attached on the UI Text Element uses the FixedUpdate method to update the total number of monster on the field to the user.

Since school starts up in a couple of weeks, I’ve outlined the final modifications I’d like to make to my game before ending the game development portion of my project. You can read the list of modifications I’ve outlined below.

Gameplay Mechanics:

  • Move teleport location to the top of pillar and teleport player there
  • Improve endgame scenario so player can view total kills before restarting the game

Aesthetic changes

  • Change spawning location to an elevated platform that destroys once the player leaves it/after 10 seconds elapses
  • Change object coloring to make things stand out more (for example, it’s hard to make out the difference between the bullets and the floor)
  • Change monster prefab and add animation system (current prefab has no animations for me to work with)
  • Path monster directly to tree when approaching you
  • Add rumble to controllers for
    • Ready for weapon switch
    • Actual weapon switch
    • Weapon fire
  • Add sound effects to the game
    • Bullet sound effects
    • Monster sound effects
    • Song (if time allows)

Additionally, another task I’d like to complete before heading into school is finishing my Udemy course. I’ll be finishing my internship soon, so I hope that the additional 8-9 extra hours I’ll get each day will help me substantially in finishing my project.

Goals for this week:

  • Complete half of the bullet points established for completion
  • Complete at least 75% of the current Udemy section I’m on

 

Nearing Prototype Completion

We’re getting there! Almost all the pieces of my game prototype are put together, and soon I’ll be able to start polishing it for the October Hackathon Showcase. I’ve attached a video of me walking through the current prototype.

The entire monster generation system is now function. To do this, I made a new script entitled monster generation, along with some additional modifications to the TerrainGeneration spawner. Since TerrainGeneration spawns monsters upfront, I created a static variable that kept a count of all spawned monsters, and two static variables which denoted the minimum and maximum number of enemies which could be on the field at a time. These were used in the monster generation script to enable and disable the spawning system. If the total amount of monsters spawned are less than the minimum amount of monsters allowed on the field, a coroutine is activated which continually spawns enemies on a random tile with a two second delay until the total number of monsters on the field exceeds the maximum number allowed. In order to prevent monsters from spawning on the tile a monster is already attached to, I also attached a script to the floor prefab which checks if a monster is on the tile. If it is, then we will access a public 2D array containing what objects are on said tile in the TerrainGenerator script, and use the x and z positions on the tile to get the indices that correspond to the tile we want to check. From there, OnCollisionEnter updates the array with a MONSTER enum value if there is a monster on the tile, and a NONE value if there isn’t.

My next plan was to spawn enemies from the sky instead of the ground, as it is a little less jarring seeing them falling from out of view instead of spawning out of nowhere on the ground. While it was simple to spawn monsters falling from the sky (add a vertical offset in the y direction during instantiation and then add an impulse force to the negative y direction to translate its motion downwards), as soon as they collided with the ground, they would no longer move towards the player. After a few hours of experimenting with different ideas, I discovered that if I reactivated the NavMesh agent component once it hit the ground, then normal tracking would occur again. To make a long story short, I simply disabled the NavMesh agent component on the prefab, and scripted it to enable upon colliding with a floor object.

The last thing that I had to implement was a game resetting mechanism, which I thought would be an incredibly simple thing to implement. That being said, I was humbled very quickly as I spent four days trying to get the system working. To begin, I placed a cube collider underneath the player’s feet, along with a rigid body object to apply physics to the player. In order to restrict the effects of gravity and collisions on the player, I made the player’s rigidbody component kinematic. However, once the tree a player is on gets destroyed, they are no longer kinematic and gravity begins to affect the player. Once they hit the ground, the game reloads. Upon testing it for the first time, I ran into a major problem: upon reloading the game, my entire teleportation mechanic was broken. Firing the arrow would no longer have the chain effect following it, you would no longer teleport, and the bow would remain drawn even after firing it. I was getting console errors saying that there was a MissingReferenceException for my TeleportPlayer script. After quite a bit of research, I determined that the issue had to deal with the events I was using in the arrow class. This StackOverflow post boils down the issue I was having: since the events I was using for arrows landing were static, they were not being destroyed and recreated upon reloading the level. To fix this issue, I modified the events located in the Arrow class so that they are set equal to null, along with a new static boolean that signals when events have been subscribed to. In the TeleportPlayer script, we subscribe to our events if the new static boolean is set to false (meaning the events are null). Now, upon reloading the game, the teleportation mechanics work once more. That being said, the monster generator seems to be inactive upon loading the game, so I hypothesize there is another issue somewhere in my generation script involving static booleans, which i will look into later.

Unfortunately, due to the bug I encountered with the monster spawning mechanism, I was unable to research and implement a solution for a UI which tracks enemies destroyed and the health of the tree, so I’ll have to move this deadline back once more.

Weekly Goals:

  • Research and add UI to display – 8/2/2017
  • Return to Udemy Course and begin new section -8/3/2017
  • Brainstorm ways to polish the game and improve its looks – 8/4/2017

Getting Stuck, Game Dev Meetups, and Re-evaluating Goals

While it’s been almost three weeks, a combination of life, differing responsibilities with work (both at my internship and with a freelance project), and troubleshooting countless bugs in my current prototype, I have had trouble finding time to make serious progress on my game development plans. As a result, I’d like to use this post to detail progress, restructure plans, and also recap a Game Dev meetup.

To start, let’s talk about successes: one mechanic I implemented successfully was a tree destruction mechanism, along with bullet damage and monster deaths. The tree destruction mechanism didn’t take me too much time to actually write, as I had a simple implementation in mind. Debugging it and getting it to work, however, was much more challenging. I started by writing a class titled “TreeHealth,” which is attached on all tree objects in the game. It contains two instance variables which keep track of the health, and when the player is on a tree. There are two getter methods to access these variables as needed, and OnTriggerEnter and OnTriggerExit methods which check for a collision with the player and sets isPlayerOnTree to the appropriate value. Another class, entitled GroundMonsterHealthDamage, is attached on all monster objects. Here, there is a private instance variable of type TreeHealth called “treeToAttack.”  In its OnTriggerEnter method, we check if it collides with a tree object. If it does, we grab the TreeHealth component on it, and use a getter for isPlayerOnTree. If the player is on that tree, we set an instance variable in the GroundMonsterHealthDamage script to true which allows us to attack the tree as long as the treeToAttack variable is not null. Once OnTriggerExit is called, treeToAttack is set equal to null. For the bullet damage implementation, all bullets are simply tagged with the string “Bullet.” If the collision that occurs in OnTriggerEnter has a tag of bullet, then the monster takes damage, and is destroyed when its health is set less than or equal to zero.

My issues with the tree destruction mechanisms stemmed less from the code, and more from setting up colliders on the player, trees, and monsters. I had to do a lot of experimenting to get the player to collide with the cylinder, and even did this by fiddling with the transportation technique. One issue I have is where the player teleports to after they hit the tree, as sometimes it seems as though you’ll land right on the tree or float in the air slightly away from the tree. This is because the teleportation mechanic teleports you forward every 5 chain links, and there’s no guarantee how close you’ll land to the tree as a result. To fix this, I modified the delegates in the Arrow class to also pass a reference to the arrow object. From there, I grab the transform attached to tip of the arrow, and get the vector representing the direction of the Y axis (see below – this is the green axis that points away from where the cylinder hits, which is the direction we want to offset the player). I then use this vector and place it’s x and z values into a new Vector 3, and add an offset specified in a public instance variable. This ends up being the last position you teleport to once the teleportation co-routine responsible for movement is called. Teleportation feels a little more consistent now, but sometimes it feels like you teleport to the other side of the pillar – I will come back to this topic later on in this blog post.

When I planned on implementing a monster navigation system, I was only expecting it to take a handful of days to complete. At the time of writing, I’ve spent about a week trying to get a monster spawning system working reasonably with a wide variety of successes and setbacks. I’ve used the navigation mesh a couple of times in some tutorials before I started my step project, and assumed that it would be fairly simple to implement it as my terrain is mostly flat with some obstacles. However, I didn’t account for the fact that navigation meshes (also refered to as nav meshes) are usually baked (a term used to refer to the creation the actual navigation mesh) before starting the game. Since my game is generated at run time, the traditional method of baking a navigation mesh is not applicable. However, I was very lucky to discover that Unity recently added an update which allows for you to build navigation meshes at run time. Initially, I couldn’t find any resources on building run time nav meshes, so I spent a few hours using the scripting API trying to build my own implementation. After trying to debug why my implementation wasn’t working, I ended up looking for more information again on run time baking, which led me to this video. It quickly details how to build a run time nav mesh using some external scripts provided by Unity. In the implementation from the tutorial, you simply take the NavMeshSourceTag script and attach it to all terrain you want to generate, and then use the LocalNavMeshSource script to create an invisible box which sets the bounds of the navigation mesh. I actually resize this box at run time to fit the entire play area depending on the terrain generator specifications. Then, you can simply add navigation mesh agents to your monsters mand script their movements. For this, I used Unity’s manual to actually set up and script the movement. My current issue stems from the fact that monster movement is very jittery, as the monsters simply start moving and then suddenly stop, before restarting movement.  I spent a lot of time just testing out and tweaking a bunch of things to try to fix this issue, but couldn’t isolate the issue.

At this point, I decided to hold off on working on it until the Central Ohio Game Development Prototype, Play, and Build Workshop,  which I had actually planned to take a prototype of my game to as one of my goals. Unfortunately, I didn’t have anything playable, but I thought that I would at least take my current build to the meetup and get help on my current nav mesh bug. I actually met an OSU graduate who had done work in Unity and was more than willing to help me out, but unfortunately (or maybe fortunately?) I couldn’t reproduce the bug while at the workshop. That being said, I was able to get some feedback about the game itself from him. His general notes involved it being somewhat disorienting being suspended above the air without a platform under him and having the player potentially teleport to the top of the tree instead of the sides for greater visibility. I also wanted feedback on the teleportation system, and he said it mostly felt normal. However, I had a detailed discussion with him about the teleportation modification I was making, and he was able to pick up on one small nuance that I was missing. While it is possible to get the Y axis direction of the arrow, you need to actually check the direction it is pointing in world space to see whether you need to add or subtract it. For example if the player moves in the -X direction towards a tree, you’ll want to add the offset when adjusting the X direction, while doing the opposite when moving towards the +X direction. I do not know if I will have time to apply this fix (or how I would go about doing it), but it’s something to consider if I have additional time to fix up my game.

Finally, let’s talk about new deadlines:

I’m essentially going to break my VR project down into a list of things I need for a finished game prototype, and scale back on some of my goals in the game design document I made. This is to ensure that I at least have something playable by the time school starts this August and I won’t have to worry about developing on top of classes.

Things to complete:

  • Fix monster movement (if jittering reappears) – 7/19/2017
  • Add monster spawning mechanism – 7/20/2017
  • Spawn monsters from sky falling (a change from my initial monster spawning plans that prevents a monster from just appearing in front of your eyes)  – 7/22/2017
  • Script player falling and dying as an end game condition – 7/23/2017
  • Add UI Elements – 7/27/17

I am most likely going to delay my Unity Coursework tutorials until my prototype is completed, as I really want to just sit down and finish this without worrying about doing tutorials as well. Beyond that, I don’t have anything else to report, except that I hope I have a new blog post next week with a lot more successes than setbacks!

 

 

Switching It Up and More

For over a week, I’ve been making serious progress into my game development. I successfully implemented all three goals of my goals – implementing all arrow restriction mechanisms (fire one arrow at a time, restricting teleportation to only trees, and increasing arrow travel speed), added a weapon switching mechanism with actual gun models, and shooting mechanism. I’ll briefly go over how I implemented each one.

Arrow restrictions:

I’d like to note that all arrow restrictions where done by modifying the SteamVR arrow scripts: these involved the ArrowHand.cs and Arrow.cs scripts. ArrowHand is responsible for spawning arrows in your dominant hand while Arrow takes care of arrow physics.

  • In ArrowHand.cs, I created a private static Boolean titled isArrowInAir with get and set methods to allow for modifications from external classes. In the ArrowHand.cs class, there is a method titled FireArrow which fires the arrow after it has been knocked on the bow. In this class, I set isArrowInAir equal to true and used this Boolean to restrict access to methods within the ArrowHand class, particularly the ones that spawn arrows and allow for bow interaction. In Arrow.cs, I set this variable to false when a collision occurs, which causes another arrow to spawn in the player’s dominant hand. Finally, there is another instance where isArrowInAir is set false in the TeleportPlayer.cs when the arrow times out.
  • For restricting teleportation access, I created a tag titled Tree, changed the tree prefab so that it was tagged as Tree, and modified the delegates so that they took a string as well. When a collision occurred, I then passed the tag on the object the arrow collided with into the delegate. In the method that was assigned to the onArrowLanded delegate in the TeleportPlayer script, I then check to see if the string passed in is equal to Tree. If it is, the player is teleported to the arrow’s location.
  • Increasing arrow speed was a simple fix – I just increased the public variable values in the longbow class.

Weapon switching mechanic:

  • I wrote a class titled WeaponSwitch which manages the entire game mechanic. To set it up, I began by attaching the guns onto the player’s hands and disabling them using Unity’s game design interface. When the game starts up, SteamVR uses a class titled ItemPackageSpawner to allow the player to pick up a bow and arrow instance in the game world. When a player picks up the bow and arrow, the actual bow and arrow items spawn in the players hand. I then initialize some class variables used to hold the longbow and the arrow hand since they have now spawned in the environment. To switch the weapons, I attached a cube collider to the back of the players head, and scripted a separate class titled CollisionChecker for each of the hand objects. When the player puts one of the hand controllers into the cube, it sets a static Boolean variable to true in the WeaponSwitch class, and then becomes false again once it leaves the cube. When both are set to true, the player can squeeze both grips, and the weapons are then switched by enabling the gun models and disabling the longbow and arrow models. Once the weapons are switched, a coroutine is activated for half a second which restricts weapon switching with a Boolean value.

Weapon Firing mechanic:

  • A very short script titled WeaponFire was developed and attached to each gun object. A bullet prefab, which for prototyping purposes is a gold, metallic colored cylinder, is instantiated when the player pulls the trigger on their hand controller at a bullet spawning location attached on the controller. Then, the Rigidbody component is taken, and its velocity is set equal to the vector representing the direction of the bullet spawning location’s z-axis (its forward) and multiplied by a public float variable representing speed. Outside of the script, I attached a Trail Renderer component to my bullet prefab to create a tracer effect. If you’re interested in your own tracer effect, here is a link to the tutorial I used.

Here’s a video demonstrating the current implementation I have. There’s only audio for the bow and arrow, because since I am using a modification of SteamVR’s finished bow and arrow classes, it already has sound effects.

Finally, I almost got halfway through the Puzzle Ball game I’m making in Unity. I didn’t get all the way through due to extraneous time working on the arrow restrictions, but I hope to find time to complete it sometime this week. I do believe completing it will be beneficial to my game development goals for this week, as we will be going through some AI development in this section, and I have a goal this week where I will be implementing a navigation mesh system to have enemies track the player.

Goals for this week:

Note: some of the development goals I set in the initial game design document must be pushed back, as I am slightly off schedule. However, I am still on track to complete the prototype by the July 8th deadline.

  • Finish monster assets to use, and implement a monster generation system that paths to you.
    • Estimated date of completion – 6/29/2017
  • Script player health, monster health, and monster damage
    • Estimated date of completion – 7/1/2017
  • Finish Puzzle Ball section of my Unity coursework, and if extra time, start next week’s content.

Grappling Hooks: How Do They Work? (Also, new game plans)

As another week passes by, more has been discovered about Unity game development and more has been planned for future games. I’m excited to say that I’ve completed another Game Design Document for my survival shooter game. Taking the game mechanic I implemented from the tutorial I completed last week, this game will have players zipping along trees using the bow and arrow grappling hook, but will also see them using weapons to defend themselves from an onslaught of enemies as they attempt to knock down the trees the player is attached to. Most of the game is provided in the document below.

Grappling Hook Survival Game

In addition to planning out the game, I wanted to dive back into delegates and understand that functionality of C# better.

I was surprised that I had never come across this topic before while taking my software courses, but after a quick google search about delegates in Java (Java being the language my software sequence used), I discovered that there simply wasn’t a feature like it available. After programming a few examples from different Unity tutorials and reading some different pages on the topic,  I have a better grasp of its usage.

Delegates in C# act as pointers that point to different methods, which can be prepared and executed later. This essentially means that you can declare a delegate in your program, and construct a pointer which you can use to point to other methods. Once you set up the pointers, you can call the delegate, and it will execute the methods it points to. This means that you can assign (and remove) multiple methods to a delegate by using the += and -= expressions, and then simply call the delegate you made to execute them. If you’re curious about delegates, you can read a more in-depth explanation with examples here.

Another topic I wanted to learn more about was Coroutines. In the context of Unity, a coroutine will pause execution once a yield is returned to the user. From there, it will continue when the next frame is called. This allows a user to extend functionality across multiple frames from a single method instead of utilizing Unity’s different Update functions. This would have simplified some of my code in my first game; instead of calling FixedUpdate and subtracting the time, I could have triggered a coroutine once where it would be taken care of at each frame update. More on coroutines can be found here in Unity’s Scripting overview.

Taking this knowledge, I wanted to try to examine the code in the grappling hook tutorial once again, and understand it a little bit better. Essentially, we began by making a few small adjustments to the Arrow class provided by valve. A public delegate named ArrowAction was created, which takes an Arrow object as a parameter, and two public ArrowAction events were created and titled OnArrowLanded and OnArrowReleased. Once the arrow was released, we pass the arrow into the delegate event OnArrowReleased, and when it collides with an object while moving at high speed, we pass the same arrow into the OnArrowLanded delegate event. In another class we wrote, TeleportPlayer, we assign the OnArrowReleased and OnArrowLanded events to our own methods which takes the Arrow as a parameter.

OnArrowReleased creates a new line renderer, sets the total amount of line segments it has to zero, and then adds it to a dictionary data type which accounts for an arrow and its corresponding line. Meanwhile, we modified Unity’s Update function with a for each loop that goes through every arrow in the dictionary we created. For each arrow, we add a new segement to the line by incrementing the positionCount, and then set the position of the new segment to the location of the arrow. OnArrowLanded takes the line renderer based on the arrow passed into it, destroys the arrow attached to it, and starts a new coroutine called ArrowTeleport which takes the line renderer we just made. We then create an array which will store the positions of each individual line segment, and then use a for loop to update the player’s location relative to the world based on those line segment positions. Afterwards, we destroy the line renderer, and have moved to our new location.

Now that I understand what the code was doing, I set out to fix a major bug which was breaking the mechanic. If a player shot an arrow outside of the bounds of the map, the arrow would continue traveling forever, increasing the amount of line segments infinitely. Eventually, arrow teleportation would break, and the console would throw an error saying, “Invalid AABB a.” After some research, it turns out that AABB stands for “Axially aligned bounding box,” and is explained in more detail in this Unity3D Reddit thread. Truth be told, a lot of people seem to be having a wide variety of bugs in their own projects due to a wide range of issues. I hypothesized that my issue was that an infinite amount of line segments was being rendered, so I wrote another coroutine titled ArrowTimeOut which took both the arrow and line renderer as a parameter. The code essentially checks if the line renderer object is  not null, and if it is, it uses a method titled WaitForRealSecondsRealtime to suspend activation of elements further along in the code. I used a wait time of 10 seconds, and once those ten seconds passed, the arrow was removed from the dictionary, and both the arrow and line renderer were deleted. However, if the object is deleted and causes the line renderer to become null, the coroutine will simply end its execution. This seemed to partially fix the problem; shooting arrows off the map no longer seem to be a problem, as they are simply deleted before they break. Despite that, I got different AABB errors when I seemed to rapidly fire arrows from the bow while playing it again. Moving forward, I will most likely fix this by modifying the scripts to only allow you to fire a grappling hook instance one at a time, or by deleting the flying one once firing it.

I also said I was going to try to reverse engineer the SteamVR scripts provided in the interaction scene. I started look through the teleportation script, but quickly became overwhelmed by the amount of time it was taking to parse only a single script. Truth be told, with my experience with both Unity and C#, I just don’t have enough time right now to figure out how these components work like I additionally wanted to. As a result, I think I will stick with just tutorials on how to implement VR game mechanics.

Finally, I finished the Animation section in Unity. I basically learned how to create state machine diagrams within the Animator component which controller different animation states in Unity.

Goals for the following week:

  • Start developing new game prototype:
    • Update bow and arrow scripts as defined in the game design document – 6/18/2017
    • Find suitable gun models in the asset store, and implement weapon switching mechanism – 6/20/2017
  • Finish at least half of the next Unity course, which documents how to make a puzzle ball game – Aim to complete the entire section.

Let’s Get Generating!

As noted last week, something that I wanted to make was a procedural map generator. The idea was to generate a field of a user specified size, and to randomly generate trees on it based off a given chance value (specified from zero to one). The script works by taking a floor tile prefab (scale set 1:1) and a tree prefab object, and then runs through two for loops to generate a 2D grid tiling system along the X and Z axis of the scene. This is done by creating a Vector3 data type which has X and Z coordinates that change based off the loop variable’s index scaled by a float value of 10, and then by calling the instantiate function using the floor prefab and a transform value which was based off the Vector3 position previously made. To produce trees, a random number is generated and checked if it is less than the chance value specified by the user. If it is, then the tree is instantiated in the middle of the panel just created. Prototyping this generator was pretty quick (about an hour and a half), and had only a few notable errors. One of these bugs involved the panel locations being adjusted in the y direction as opposed to the z direction. As a result, multiple planes of panels were layered vertically. An image of this is provided below.

To fix this, I changed it so that I was only changing panel positions in the x and z directions. After I fixed this, I implemented the tree spawning system as noted above. I’ve provided below a picture of the fully developed level generator; however, since it is a prototype, I’d like to note that the cylinders are simply placeholders for trees. Also, I’ve attached the code as a text file for those who are experienced in Unity/C# and would like to understand the entire picture.

TerrainGenerator.txt

In addition to the level generator, I also finished the infinite runner game provided in the Unity game development course that I’m taking. I learned quite a bit of useful skills from it that extend both to VR and traditional game development; most noticeably, the creation of UI menus and overlays, along as using the scene manager to switch between the main menu and the game play. Additionally, I finished the other tutorial on grappling hook teleportation, which I’ve also embedded below so you can get a good sense of the mechanic itself (it’s shown off in the first couple of minutes).

While the tutorial was very short, I was excited to learn about Line Renderers, which is a new component to me in Unity. The actual development of this mechanic was surprisingly simple and enlightened me to more potential resources to explore. It turns out that the SteamVR asset structure actually contains a sample scene that highlights a lot of the interaction systems that are found in most modern VR applications. As a result, I’d like to spend some time reverse engineering that scene and trying to breakdown how SteamVR can be used to develop VR focused mechanics. While the video was fairly straightforward to follow, I am still a little uncertain of how the scripting modifications work in this tutorial; particularly, the code that creates each individual chain link, along with the co-routine that actually powers the teleportation mechanic. Additionally, there seems to be a bug in the script that breaks the line rendering and teleportation system if your arrow never collides with an object; as a result, this is something I’d like to fix this week.

One thing that deeply interested me in both of these tutorials is the use of delegates in C#. While the Unity course I purchased had a C# section on what delegates are, I’m still struggling to understand the topic. This is something I intend to dive into over the week to really understand better, as it seems like a very important topic that has not yet been covered in my software courses.

Lastly, I’d like to address one of the upcoming deadlines I’ve proposed for myself. I initially set the date of June 9th as my final deadline for finishing my Udemey Course. Since starting a full time internship, the amount of time I thought I would have for game development was drastically overestimated. It has also become clear to me that while a section may have 10 hours of content, that does not mean it will take that much amount of time for me to get through it. I find myself working through some tutorials and getting stuck for upwards of 30 minutes trying to find out where I may have messed up my project. As a result, I am only 43% completed with the entire course. Therefore, I am going to push this date back to July 8th. I still think I can hit the game development guidelines I’ve set, but if I’m going to really explore VR game development, I need to put more emphasis on SteamVR’s tools than just doing Unity coursework.

Goals for next week:

  • Understand the grappling hook program, and fix the bug that’s disabling teleportation.
    • Also explore delegates in more detail from a software perspective.
  • Add fixed grappling hook program to the random level generator and begin to plan out next game.
    • Start writing out a Game Design Guide so the final picture of the game is more refined.
  • Explore the SteamVR interaction scene so I can better understand how VR development in Unity works.
  • Complete the section on animation in Unity through my Udemy course.

My First Game, Completed

After two weeks of hard work (and a lot of debugging), I finally completed my first video game! The video below contains an explanation of the game and how it works.

 

Coming into the last week, I had a few major systems to implement. The first one being a timer which signaled the end of the game, and also a UI which the player could use to restart or quit the game. Implementing the timer was fairly straightforward, and only involved subtracting the change in time between each call to the method FixedUpdate, which is a class Unity activates at fixed intervals (in this instance, 1/90 of a second to match the refresh rate of the VR headset). From there, the timer was updated on the screen after each subtraction. Once it hit zero, the timer stops decreasing, the scoreboard’s text element is set to “Score: 0,” and a Boolean is set to true that signals that the game is over.

I spent quite a bit of time trying to figure out how to implement a VR UI by trying to find tutorials, but resources seemed to be scare. Initially, I learned about another VR scripting toolkit called “Virtual Reality Toolkit (VRTK).” It works with the SteamVR assets, and seems to further simplify the development process of VR applications. I spent about an hour trying to figure out how to interact with UI elements using this toolkit by following along with a youtube tutorial. However, after I was struggling to get pointer interaction to work with the defined GUI space, I opened up an example scene provided by VRTK and tested it out. Unfortunately, even there I was unable to interact with the menu elements . I hypothesize that this is due to developing in Unity 5.6, which has potentially broken some of the components and scripts provided in the tool kit. While I wasn’t able to use Steam VRTK to implement a UI, I still think this is a valuable toolkit to learn how to use, as it seems to provide a lot of quick and easy tools to do VR development.

Since I was struggling to implement a UI and running out of time to complete the project on schedule, I opted for another 3D text element like the one on the board, and implemented the grip press as a method to start the game. While starting the game wasn’t incredibly challenging to implement, I struggled a lot with figuring out how to reset the game. My goal was to use the Instantiate method to initially load my prefab into the game world, delete it when the game ended, and re-instantiate it into the world afterwards. When I tested this out, the game would successfully instantiate the prefab, but fail to reload the balls onto the rack once the game ended. When I checked the console, I was getting an error telling me that I was receiving a null pointer exception for the prefab, and that I most likely failed to attach these components in Unity’s inspector. This tripped me up a lot, and I spent about four hours trying to figure out why I getting this error, as I had clearly added the prefab into the scripting component. That being said, I actually found the problem seemingly by luck, and it actually turned into a great learning moment about inheritance in C#!

I initially wrote my BallController script so that it inherited the ScoreController class, and then from there the ScoreController class inherited MonoBehavior, which is a class that contains access to most of Unity’s scripting features. Initially, I thought that this would be an easier way of accessing methods and static variables to use in my ball controller, but learned by accident that I get null object pointers for every object that inherits ScoreController. As a result, I needed to reattach everything I had on my score controller game object (which held the ScoreController script) onto each and every ball I had in the game. To fix this issue, I had my BallController script directly inherit the MonoBehavior class, and then rewrote the score controller class so that the methods and variables I needed to access were public.

Moving forward, I learned that I tend to script my projects very messily. I think I should focus more on managing my code so that it’s a little easier to read, and that I comment out and organize my code a little bit more.

My other goal, however, involving my courses fell through the floor. Now that I’ve started working full time, it was hard to balance development and the debugging of my actual game with the tutorials I planned to complete. That being said, I found a really nifty channel called FusedVR, which has a lot of quirky Unity tutorials for the HTC Vive. One of their tutorials is about building a grappling hook in Unity to teleport around the map. I actually already have a game idea based off of this which I want to explore further, but still want to flesh out the ideas a little bit more first. However, I do want to play around with a terrain map generator, which essentially spawns in trees across a planed based off of a tiling system.

Weekly goals:

  • Begin experimenting with a tiling system that randomly generates trees across a map.
  • Finish the infinite runner game I was working on as a part of my Udemy course.
  • Complete grappling hook tutorial.