Sunday, June 28, 2015

Max Proof: Finishing the HUD

  Hey guys, I know I said in one of my previous blogs that I would go over the last few functions of the HUD class or in other words the Inventory. In this blog I actually wanted to go over the final pieces of the Inventory functionality that I created for Max Proof. These last four functions are fairly simple and once one of the functions were created I was basically able to transfer that functionality over to the other functions. To begin, I mention in my previous blog that once quantity of an item is equal to zero, the graphic of an image will change. These four functions will handle that logic. For each item in the inventory I created a binding to the Brush.


  Upon creating a binding to one of the graphics in the inventory I begun creating the logic. Before I went about doing this though, I created four variables of type Slate Brush; CurrentImageG, CurrentImageB, CurrentImageT and CurrentImageL. The purpose of these variables is to hold the brush values. In the beginning of the function I want to do a check. If CurrentQuantityG is equal to zero then set CurrentImageG to the graphic that indicates to the player that we are out of this item. If false have the default image be the image assigned. Afterwards we want to return CurrentImageG. Having this function binded to the brush allows us to dynamically change the inventory graphic depending on what quantity is.


  Now that we have this function done I begun duplicating the logic onto the other functions I binded to the graphics. Thus completing the HUD for Max Proof! The great thing about having our logic like this for the HUD and as well as creating a dynamic item class is upon creating other levels for Max Proof, all we have to do is throw hazards of Item into the scenery and everything will work perfectly. Having achieve this we were able to minimize the amount of additional logic we would have to create when beginning a new level. With that being said, onto the next task!


Max Proof: Finishing Item Blueprint

  Hey guys, I wanted to continue from where I left off with the Item Blueprint. Previously in the blueprint I was working on creating the construction script for the class to where we can allow anyone such as designers or anyone in my team to be able to change the items mesh, material and collision. Having complete the construction script I was ready to jump into creating the full logic for the item class. To give a brief description of the classes purpose; in Max Proof, players have the opportunity to grab different hazards in the level and move them to prevent Max from getting hurt. These hazards are considered to be Items in the level. So with that we know well one, players need to be able to have the ability to drag and drop them in the game world and two, if the player fails to move them from Max's reach well there's a point deduction. With knowing this information we can begin our logic for this class. Very similar to how we creating the drag and drop for our HUD items, we can apply this same logic for our Item class.
  You may recall in one of my previous blogs that I discussed the issue with creating a smooth drag and drop with the HUD versus any other class blueprint. In any other class blueprint, we have the option of creating on click and on release events. In widget classes we only have the option of creating on click events. When it came to creating the movement logic for our item class, it was far more smoother and vastly simple to do. To begin I created a function called SetActorPos.


  In SetActorPos I created three variables; bool MouseBtnHeld, vector MousePos and Item ItemObj. The purpose of MouseBtnHeld is to check when the mouse is being pressed on an item. So with this check we can say hey, when this is true at every tick get the mouses position and assign that to the actor position. Now this is where MousePos comes in. MousePos gets and updates the X,Y position of the mouse. You may be wondering, whats with ItemObj? Looking at the picture above we assign the target of SetActorLocation to ItemObj. Keep in mind ItemObj is of class Item so we're basically saying hey...For every hazard of class Item, we will update it's position upon click. Now the different thing we did with this variable is allow it to be editable. Doing this now allows you in the editor to say what each instance of the class is. So let's begin the logic! When SetActorPos is called we do a check. If MouseBtnHeld is true, continue the logic; set MousePos which is given through breaking a vector that receives a hit result under a mouse cursor. Afterwards SetActorLocation using the parameters ItemObj and MousePos. Now that we have this done we can begin creating our last two functions.
  These next two functions I created were more towards if someone decided to play this on PC. In all honesty we could've took these functions out during refactoring but we decided to leave it for the moment. The two functions I created are basically HoverBtn but for hazards. So whenever we go over a hazard, the mouse cursor changes images. These two functions I created are called SetHold and ReleaseHold. In SetHold we say hey, we have officially clicked and are holding on a hazard so change the image. In ReleaseHold we are saying, we have now released the mouse button so now changed the image once more. So let's begin!


  Looking at the image above upon calling SetHold function we are setting the mouse cursor's image to GrabHandClose and the target is Get Player Controller. Afterwards we set MouseBtnHeld to true because when it's true we're able to dynamically move the actor. Similarly in ReleaseHold we have the same logic but Instead we have the image be GrabHand and we set MouseBtnHeld to false.


  Thus ending the last two functions. Now that we have that over we can now begin the last part of the class which is the Event Graph. To make this class come to life in Max Proof we now need to call these functions made. On InputTouchEnter and OnBeginCursorOver we set the mouse cursor image to GrabHand. On InputTouchLeave and EndCursorOver we set the mouse cursor image back to default. On Click and OnTouchBegin we call the SetHold function. We do this because upon clicking the image, we want it to look like its visually being held and plus it allows the SetActorPos to become active. To continue this OnRelease and OnTouchEnd we call the ReleaseHold function. Lastly to end the class on EventTick we call the function SetActorPos.

So now if we were to throw instances of this item class into the level, we can drag and drop now.



Saturday, June 27, 2015

Max Proof: Item Blueprint Construction Script

  Now that we have the majority of the Inventory working I wanted to jump into our hazards logic. The point of hazards in Max Proof is to basically have items that are dangerous become obstacles for Max when he ventures in the level. Upon stumbling on a hazard, points will be deducted. When we thought about creating hazards for Max Proof we wanted to make this as dynamic as possible. Having four years experience with Unreal Engine 3, I know the hassle you would have to go through to create logic for each individual item that does the same thing. Fortunately for Unreal Engine 4 they have class blueprints. So if I wanted to create a door that opens and closes, I can do it once and drop the blueprint as many times as I want in the level and the logic will remain. So when considering this how can we have a dynamic class that keeps consistency of the same logic? We can definitely do interfaces. In fact interfaces would be perfect for situations like this. Now having said that, we actually went a different route. My goal for this was to have one class that does it all. Thankfully in Unreal Engine 4 they introduce Construction Scripts.
  In a Construction Script, you have the freedom to create logic that will run while in the editor. So what we did was create a generic item blueprint. In this Item blueprint we wanted to throw it in the level and then in the details panel be able to change the default mesh to whatever mesh we want it to be, change the material for that mesh, as well as the collision response for that mesh. So what we we're doing here is hey, all logic for the items are the same however, these items are different visually. Upon creating the item blueprint I two components; a static mesh and a trigger volume as a child of the mesh.


  After doing that I went into it's construction script and created four variables. One of type Static mesh and I called it Custom Mesh. The other of type ECollisionResponse and I called it CollisionResponse. The next one of type ECollisionChannel and I called it CollisionChannel. The last was of type Material Instance and I called it Material. After creating all variables I went to each one and checked Editable. Now comes some logic for the construction script.
  At the beginning when the construction script runs we have it where we set a static mesh, the target is CustomMesh. Then we set Collision Response to Channel. The Channel is CollisionChannel and and the response is CollisionResponse. After that we set Material of the mesh and the target is Material.

  So if we were to jump into throwing an Item blueprint into the level, once clicking the item in the scenery we can see a few things added into the details panel. In the editor we can now change the item's static mesh, material, and as well as the collision response/channel. Now you may be wondering what's up with ItemObj and what does that mean. ItemObj actually identify s what object it is of that class. This will be discussed in a future blog where I get into creating hazards that can similarly to the inventory be able to pickup and drop into the world. Stay tune!

Max Proof: Polishing the Inventory

  Hey guys, haven't been on for a while and thought it be good to continue from where I left off on the Inventory for Max Proof. The great news is we fine tuned the Inventory and everything is working smoothly! After we completed the inventory we did some refactoring and took out anything we felt was unnecessary. Sadly considering this project is under development for mobile, we decided to remove the "HoverBtn" function. To give an idea of what HoverBtn was about, well the purpose of the function was to dynamically change the mouse cursors image when the player hovers over an inventory item or even a hazard in the scene. Having said that I wanted to go over the neat features we added on to the Inventory.
  To break it down, we added in the feature of quantity..So whenever the user touches or clicks a button, depending on the item in the inventory, a deduction in quantity will occur. Upon quantity of an item being zero, we changed the graphic to the same graphic but with an X to indicate that hey...You probably can't use this item now. We as well made it that upon quantity being zero, all other logic for that specific item would not work. Considering this, we created a few getters and setters. But before I get to ahead of myself we need to graphically input quantity into the inventory.
  Jumping to the design view of our HUD blueprint I created four text box's having them overlap each button individually. Each text box I named them accordingly to its designated item such as; BoardQuantity, TapeQuantity, LockQuantity and GateQuantity. After doing so in Content > Text I hit create binding for each of them. The point of doing this is to well...Bind a function to the text. The function I want to bind is a kind of function that will practically know what the text should be and how it behaves. What great way to use getters and setters! So in other words the function i'm creating that's going to be binded to this text is a getter function.

  To make my life simple since I know we will have four getters due to four items in the inventory, i'm going to need four integer variables that hold a value for the text; CurrentQuantityB, CurrentQuantityT, CurrentQuantityL and CurrentQuantityG with each default value of five. After creating the bind for the first item; board, I had the function basically return a text of CurrentQuantityB. After doing that I continued the process of binding for the other three items.

  Once completing the binding for each item in the inventory I begun creating the setters. The point of the setters for quantity is to well...Deduct. So when the function calls do CurrentQuantity -= 1; Now after doing this I ran into the situation where yea my logic works but for some reason every now and then when I grabbed an item from the inventory it would just decrement to the negatives which was weird. So I basically hard coded it to make sure it remains zero once reaching zero. In the setter function that I created for the Board I basically said, set the CurrentQuantityB -= 1 and if CurrentQuantityB equals zero, set it to zero. Having done this resolved the issue preventing the quantity from continuously decrementing when it shouldn't be. After doing this I continued this same logic for the other items in the Inventory. Thus ending the quantity logic.

  But wait, similar to the drop item function if we were to play the game you would see nothing from quantity. Reasoning why is because we never implemented it in the Event Graph. Jumping to the Event Graph we ended up fine tuning some of the logic on the events OnClicked. For OnClicked(IS0) we previously saw, on click > DropItem and thats it. Now for each of these events there's more logic that helps polish the inventory further. Since we implement a timer in the game we begin by checking hey if isTime0 false then do this; set BoardBtnClick to true then check if CurrentQuantityB is equal to zero. If False continue the logic; Drop Item and then set BoardBtnClick to false. Now your probably wondering whats with the bool statement with time and where did BoardBtnClick come from. To answer the question if that was a thought well... BoardBtnClick is a bool variable I created. The purpose of this variable is to check when the button has and has not been clicked. If it has been set to true, then use the setter function we created. Unfortunately, I won't be going over our timer functionality because I don't want to take credit from my partners work but I will say he did a fantastic job! To get back on topic I continued this logic for the other four buttons.


  To dive in further so we can actually get the quantity running when playing the game I added on into our drop item function. Inside the function I added a few more if statements. If BoardBtnClick is true; use it's setter...If false check if GateBtnClick is true; use it's setter and continue on with the other two items. Having create this logic, when running the game the quantity works now...Which is awesome!

  All that's left to completely end the Inventory is a few things that need to be added into our game loop. In our game loop we currently have it where we can dynamically set the mouse's position as well as the actors position. On top of that we can drop the item anytime we want. So what are we missing? Well originally when I created the logic for the game loop I had it when we click the item. Keep in mind the primary development of this game is to have it set to mobile. Having said that we need to add logic in that also checks when the user touches it using a smartphone. In the logic where we check Is Input Key Down > Left mouse Button. We added an OR operator to the Boolean statement. So if Input Key Down > Left mouse Button OR Input Key Down > Touch 1. This will allow us to check for both PC and Smartphone. To continue our loop logic we needed to consider our timer. We don't want the player to grab items in the inventory while the timer is equal to zero. To prevent this from happening in the beginning of the loop we added a if statement. If isTime0 is true, destroy actor > Target Actor. If False; continue the logic.


  Now you may have notice from the image above that there's another function by the name of MouseOverVolume. The way we wanted this game to work was to allow the user to only drop inventory items at specific locations. The purpose of MouseOverVolume is to do that. In the function MouseOverVolume we check a hit result. If the mouse cursor (considering the actor follows the mouse position) hits any object type of destructible, set a new variable called Collided to true. Otherwise set it to false. Now you may be wondering why did I choose destructible? Well in the list of arrays to choose from, we had no option of only grabbing actors or specific actors. Considering we're not planning on creating a fracture meshes or anything like that, why not make our actors more specific by saying their destructible.


  So now looking at our Event graph, at every tick we call this function. Since we added this function we also need to do another check. If we have Collided, then now we are able to drop the item, if we choose to not drop it then continue calculating the mouse position and setting it to the actor position. If we were to play the game now everything is practically working as it should. We can grab the item in the inventory, drop it at a specific location as well as see that quantity on a item is being deducted. This concludes the majority of the inventory functionality. All that's left is creating logic that swaps out the graphic of the inventory item when quantity is zero. That part I will go over in a future blog!