Levi D. Smith holds a Bachelor of Science in Computer Science from the Georgia Institute of Technology and a Master of Science in Industrial Engineering from the University of Tennessee. He has been developing games in his spare time for over twenty years.
This is the last few weeks of the Dream Build Play 2017 competition, and I’ve decided to put my action-RPG game Myriad on hold. The game just has too far to go in order to make it a completed game and respectable entry.
In it’s place, I’ve decided to make Turn Back the Clocks 4 my Dream Build Play entry. Honestly, I’ve enjoyed playing it more than any of the other games I’ve created. I started working on the game in early November, so using it does not break any rules of the Dream Build Play competition. Plus, there’s a story that goes along with the development game, since it was originally created for the 0hGame jam in an hour.
I’ve spent the past few weeks improving the gameplay and graphics. I feel like there’s just a little more to do to make it a complete game. I need to fix the way the balls move in the line as they are shot. Right now, each ball just targets the position to where it needs to move, but that doesn’t work correctly when the balls are shot rapidly. I would also like to have the score display for each clock hit, in the color corresponding to the ball which hit it.
The game already has leaderboards implemented, so I’ll just need to remove the screen with text entry to use the XBoxLive services. I still plan on using my own host to store the leaderboard information, so I’ll just pass the user’s gamertag and score to the leaderboard function.
I also need to do some small changes to graphics. I want to make the board a little lighter, so that the balls stand out better. Then I will need to make the inactive clocks darker, so that they stand out against the board.
Modifying the controls to work on XBox One shouldn’t be too big of a problem. I’ll just need to assign button input events to each of the buttons, like I did with my Kitty’s Adventure game.
The following are the steps that I used for creating a health bar using the Unity UI system for my Shark Food game. Many of the settings for the size and images can obviously modified to meet specific needs.
First, create two images for the background and foreground. This can be done in Gimp, using the dimensions 512×64. For the meter fill, use the Filter > Render > Clouds > Difference Clouds. Then use Colors > Colorize to make the bar red (hue value 0) and increased the saturation and lightness. Create the background by simply filling the entire image with black (Edit > Fill With BG Color). Set the transparency for the layer for the background image to 50%.
Save both of these images in the Assets / Textures folder of the Unity project. Select both images and set Texture Type to Sprite (2D and UI) and press Apply.
Create a new Canvas object. I recommend setting Canvas Scaler to Scale with Screen Size and set Reference Resolution to 1920×1080.
In my Shark Food game, the health is stored in a float variable in my custom Shark class called fHunger. This value ranges from 0 to 100, which is ensured by using the Mathf.Clamp function after it has been set.
Under the Canvas object in the Unity Hierarchy, create two new UI > Image objects. Assign the background image to the first one and the foreground image to the second one. A Text > UI object can also be created to display the value on the health bar. Parent the foreground Image and Text object to the background image object.
Add a new UI > Mask component to the background image. Ensure that Show Mask Graphic is selected.
Create a new custom C# script for the health bar. I called mine HungerBar. Attach this script to the background image object. Open the health bar script in an editor (I used Visual Studio) and add a line of code in the Update method to set the position property of the foreground image. Use Find on the transform to get the foreground image, and use GetComponent<RectTransform> to get the localPosition property. Declare a float instance variable for the x position. Set the localPosition property to a new Vector3 with the x property set to the instance variable and y property set to zero.
Create a setValue method, which sets the instance variable to the passed in value times the health bar width in pixels, minus the health bar width.
Whenever the health value is updated, call setValue and pass in a value from 0 to 1. This was in the updateHunger method of my Shark class, which gets called on every Update.
The health bar object can be returned with GameObject.FindObjectOfType<HealthBar>(), assuming that you only have one health bar in the scene. Since my hunger value was a float from 0 to 100, I divided by that value by 100f before passing it to the setValue method. The text can also be set by using GameObject.Find and setting GetComponent<Text>.text. Be sure to import UnityEngine.UI, because it doesn’t get added by default. If the intellisense doesn’t work for the Text object, it’s usually because of the missing import statement.
That’s all there’s to getting a health bar working. It’s fairly simple once you know the steps and settings.
I spent about an hour and a half working on my new Unity game for Dream Build Play 2017. It’s been a few weeks since I last touched it, since I’ve been busy with updating the web site and other game jams. A few days ago I decided to change the title of the game to Myriad of Legends, which keeps the “My” of Mystic and “Ad” of Adventure. Then I thought the title was too long and sounds too much like League of Legends, so I decided to change the title to just Myriad, which I think sounds better. The only problem is that just a one word title will make it harder to find with search engines.
This time I worked on enemy movements. I made the Enemy Movement a separate script that is assigned to my Enemy prefab. I really wanted to keep things like movement countdowns separated from the core enemy attributes like health points. I keep an angle float variable, which holds which way the enemy should be facing, and I update the rotation on every frame using Quaternion.AngleAxis, using the angle and Vector3.up as parameters. This is to ensure that the enemy keeps facing the same way, since the rotation can be affected by the physics engine. Alternatively, I suppose I could have locked the Y rotation on the enemy RigidBody. I have a function called setRandomDirection, which sets the enemy angle to either 0, 90, 180, or 270. This is done by generating a random integer from 0 to 4 (exclusive), then multiplying by 90. I have a countdown which calls the setRandomDirection every two seconds. Also, if the enemy collides with another enemy, I add 180 to the rotation to both enemies so that they don’t continually bump into each other.
I also created a rock object, which is currently just a cube that I texture mapped in Blender. I populate the rocks in the game world according to a text file. This is the same process that I used for Ancient Adventrue and some of my other games. The text file has pound signs (#) to represent the rocks. I have the text file stored in the Resources folder in my Unity Assets folder. Then I assign the text file to a TextAsset object in the LevelManager script that I created. I can access the contents of the TextAsset using the .text property. Then I use the Split method passing a new line (\n) as a parameter to get each row, and use .ToCharArray to get the character data for each line. It’s a quick and simple way to design levels. Later, I may convert this to something like the Tiled TMX format, which would allow me to store more information, but is a little more difficult to parse. I also added enemies, which are signified by the letter ‘E’. I set the enemy movement so that 180 is added to the rotation if it collides with a rock. Occasionally, there is a bug where the enemy will continually rotate, which I believe is caused by the enemy colliding with two rock objects at once. I need to fix it so that it will only rotate once per frame and per collision. As I found out with some of my previous games, a collision can occur over multiple frames (Update calls), and it isn’t finished until OnCollisionExit is called.
I still had the problem with the sword collision box continually colliding with the player capsule collider. To fix this, I just made the sword collision box a trigger, so that it is not affected by physics. I think I could have put the sword and enemies on a separate physics layer, but that could make things much more complex. When the enemy gets an OnTriggerEnter event where the colliding object is a Sword, then the enemy is destroyed. Probably in the next update, I will make it so that it takes away health points, and only destroy the enemy if their health falls below zero.
Finally, I got rid of the huge ground plane, and added a new ground prefab. It is the same width and depth as as the rock, one unit in both directions. However, it’s anchor point is on top of the model, instead of on the bottom like the rock. This way, if I instantiate a rock and ground at the same position, the rock will sit perfectly in line on top of the ground. The ground is instantiated for all spaces in the text file, and with rock and enemy positions.