This week I focused on hammering out how to constrain the movement of my Pawn and continued developing the camera. I also worked on prize concept art!
My game type is currently extended from UTGame. I had originally extended from UDKGame, but found that my camera was most closely based on a third person camera that pivots around the Pawn (the claw.) The built in SetBehindView in UTGame is helpful for getting a third person camera working in this way. I need to remove the default HUD from UTGame, but I don’t see this as posing too huge of an issue.
My camera is based loosely on this third person camera code. The camera height and offset from the location of the player are global variables with values editable in the defaultproperties of the Pawn class. The CalcCamera() function uses these to calculate the position and rotation of the camera relative to the player.
In my version of this camera, I’ve frozen the rotation of the Pawn, but not the Player Controller, and so the camera moves based on mouse input but the Pawn mesh never turns. In the UpdateRotation() function, After getting the rotation from the mouse input and feeding it into the ProcessViewRotation() function, I clamp the resulting Yaw rotation value. This is because I don’t want to have a full view around the crane game machine – just enough to pivot and give the feeling of peeking inside the machine left and right.
My code right now allows the camera to move in location in the X and Y axes along with the claw Pawn, which is something I need to fix. This makes the camera much too active for my taste. I would prefer it to be very subtle, and for the rotation of the camera to correspond to the X movement of the crane.
I was able to constrain the movement of my claw in the X and Y axes in the PlayerController class in the tick() function. A tick is one frame, so whatever is inside the body of the function is calculated each frame. I simply grabbed the location of the Player to a tempLocation vector (X,Y,Z). I then used an if statement to check if the location in each axis was above or below my max or min values. If it was, I set the tempLocation equal to the min or max value. Then, I called SetLocation(tempLocation) to write the tempLocation to the location of the player.
I attempted to do the same on Z axis, but just set tempLocation.Z to one value, like 100, so the player would stay afloat at 100 units in height. The problem with this was that the built in gravity kept taking effect. I figured out that the best option would be to set the Pawn’s physics to PHYS_Flying. This can be done in the default properties by simply saying Physics = PHYS_Flying, or even changing it from a dropdown in editor in the properties of the Player Start. Even setting the physics to flying didn’t seem to work though – my player kept falling.
After a lot of fooling around, I ended up calling the SetTimer() function in the PostBeginPlay() function of the PlayerController, essentially causing a delay and allowing the PHYS_Flying to be calculated before the player is initialized.
I’ve designed several prizes that are going to populate the machine. Although it’s not a priority to outline every single prize, I found designing them to be a good reminder of the tone of my game. Some of these are cameos from other works I’ve done, others are new ones designed while referencing cheesy and overly sweet stuffed animals from my reference photos.
I’ve found the prizes have helped me come up with some ideas for added functionality I might want in the game. If each prize could have an individualized behavior, there would be a lot of potential for very humorous surprises with each prize you pick up. For example, the sad teddy part might fall apart in a variety of morbid ways whenever it is touched, making it impossible to save. The bubble gum fish might be extremely sticky — and hard to get off of your claw when you want to drop it. And the toilet paper – maybe you need to pick it up in the right way – over or under? By time you get it right you may have unraveled the entire roll.