I've modeled the high poly version of the crane game exterior, UV mapped the low poly, baked down the normal maps to the low poly, and began to texture it based on my reference photos.
I sculpted two of the stuffed animals I've designed. I started completely in ZBrush from ZSpheres to create the base armatures. I decided to begin these by sculpting, as it helps to achieve subtlety and a more organic, plush feel. I'll be retopologizing these, UVing, rigging, and texturing them to be put in engine and testing soft body physics with. The sculpt will be used to bake the large detail normal map. I'll also be creating a finer procedural normal map for the cloth material, as well as combining procedural textures and hand painting for the diffuse.
MR. SNUGGLE WUGGLE
BUBBA BLUB BLUB
GAMEPLAY (UNREALSCRIPT AND PHYSICS)
Here are some simple mechanisms I've been testing out with UnrealScript. I have been working mostly with placeholder meshes and cubes for the time being, just to get the principles down.
RECOGNIZING IF THE PRIZE IS IN THE CLAW'S GRIP
The claw spawns an invisible box mesh that surrounds it at level start. This box is hard attached to the claw and moves with it. Whenever a prize is inside this box, checked by a Touch event every tick, a timer starts. If the prize leaves the box, the timer is cleared. Once this timer is running, I can check to see when the timer hits a certain time and initiate functions at that time. For instance, I might want a prize's specialBehavior() function to run whenever the prize has been grabbed by the claw for a certain amount of time. After being held for 5 seconds, Mr. Snuggle Wuggle might just start falling apart.
I need to dynamically determine the bounds in the X and Y coordinates that the Pawn is allowed to move. The claw needs to only be able to move to the extent of the walls of the crane game machine, with some padding. However, I didn't want to hard code the constraint to specific coordinates. I want to be able to get the bounding box coordinates of a mesh and set the min and max values for the X and Y coordinates to the min and max X and Y values of the bounding box.
Since I would like to be able to choose which actor the bounding box is based on an instance placed in the level in engine, I made a custom Kismet node which takes in an Actor input. Here is the basic structure of my class for setting up the Kismet node with a basic in, out, and input variable.
class SeqAct_BoundingBox extends SequenceAction;
var() Actor ABox; // ABox is a global Actor variable that stores the input taken in by the Kismet node.
//The () following var signify that it can take in an input in Kismet. My Kismet node is an Action.
InputLinks(0) = (LinkDesc = "In")
OutputLinks(0) = (LinkDesc = "Out")
VariableLinks(0) = (Expected class'SeqVar_Actor', bWriteable = false, LinkDesc = "ABox", PropertyName=ABox)
When activated, I get the bounding box of the input Actor and store it to a local Box variable called BBox.
local Box BBox;
I then need to pass the Bounding Box coordinates stored in Box BBox to the Pawn class, where I can check if the Pawn's coordinates are within the bounding box coordinates. I had a ton of trouble accessing other classes, like my custom Pawn class. In the Kismet node, I found that I was able to use this function to get the active Pawn from the local player controller.
local CGPawn CGP;
CGP = CGPawn(GetWorldInfo().GetALocalPlayerController().Pawn);
I made a function in my Pawn class that takes in a Box variable. Inside that function, it stores the information of the coordinates in Box BBox to a variable that is global within the Pawn class. The function in the Pawn class is called P_BBox (for Pawn BBox).
var Box P_ClawBounds; //global variable at the top of class, for Pawn Claw Bounds
function P_BBox(Box BBox)
P_ClawBounds = BBox;
In the custom Kismet node under the Activated() function, I finally call the function I made in the Pawn class to pass the Box BBox variable over.
In the Pawn class, every tick, I check to see if the Location of the pawn is >= the max X and Y coordinates and <= the min X and Y coordinates. If it is below or above the min and max coordinates, I set the pawn location back to the min or max. I grab the Min and Max float values from the P_ClawBounds variable that stored the bounding box information from the Kismet node. I set up a temp vector variable called tmpLoc, which is set = to the Pawn's location at the time the tick function is called. I use the tmpLoc then to perform calculations on for the duration of the function, and then at the end I use SetLocation(tmpLoc) to set the location of the Pawn to the updated tmpLoc.
simulated function Tick(float DeltaTime)
local vector tmpLoc;
local float Max_X;
local float Min_X;
local float Max_Y;
local float Min_Y;
Max_X = P_ClawBounds.Max.X;
Min_X = P_ClawBounds.Min.X;
Max_Y = P_ClawBounds.Max.Y;
Min_Y = P_ClawBounds.Min.Y;
tmpLoc = Location;
if(tmpLoc.X >= Max_X)
tmpLoc.X = Max_X;
if(tmpLoc.Y <= Max_Y)
tmpLoc.Y = Max_Y;
if(tmpLoc.X <= Min_X)
tmpLoc.X = Min_X;
if(tmpLoc.Y <= Min_Y)
tmpLoc.Y = Min_Y;
RAISING AND DROPPING THE CLAW / PHYSICS GUN CONSTRAINT
A major part of making this game is to create realistic physics driven movement. I've determined that the Pawn mesh should actually be, what I'll refer to as (bare with my little knowledge of real life mechanics), the sliding mover box at the top of the machine. This is where the movement of the crane originates from. There is a string that feeds into this box that holds the claw up, and can be dropped down to drop the claw down.
I've been doing a lot of testing with all of the different physics features in UDK that I knew nothing about before this project. I've thought through several possibilities for how to make the claw attached onto the string which is attached to the mover box, and how to make the string lengthen and drop down. Here are the conclusions I came to.
The claw mesh is a rigged SkeletalMesh with a PhysicsAsset. Each separate, individually moving mechanical piece of the claw is vertex weighted to its own bone. The PhysicsAsset sets up the correct constraints between the bones (i.e. hinge) and allows physical impulses to be enacted on it. Controlling the grabbing of the claw with this rather than a baked matinee animation will allow for the physical interaction between the collision of the prize and the claw grabber, so the grabbers stop when they collide with a prize.
This all sounds good in theory, and I believe it's what I need to make happen, but experimenting with this stuff has been extremely frustrating, to say the least. Here's dismal picture of my progress, a broken claw with improperly functioning constraints lying on the cold, hard ground of the UnrealPhAT Editor.
We'll see what happens as I keep working with this. If necessary, a simpler claw model may be in the works so that things have less interdependence and chance of breaking.
The claw PhysicsAsset is then attached to a rigid body SkeletalMesh string with a PhysicsAsset instance (since soft bodies cannot hold up meshes), modeled to the length of the longest it will need to drop. This string is then fed up through the box and the top of the machine, which will be hidden to the player and so it won't matter if it clips through the top of the machine. This string would be pinned straight by surrounding collision boxes until the point where it originates from the bottom of the mover box - that way the swing pivot is at the bottom of the mover box. The string's X and Y coordinates would be locked with that of the mover box, but not the Z. The string drop, and the drop of the claw by proxy, will be controlled by a variable that determines the current Z coordinate. This variable would be clamped at the max and min height position - so that the claw can go no further up than the mover box and no further down than to the platform the stuffed animals are on. This variable would be modified by a key binding (initiated to start dropping by a key press, and an automatic raise after a designated wait time (2 seconds or so) that allows for grabbing prizes at the extent of the drop.
The downside of this method is that the string would be stiffer looking, since it is a rigid body. The string may bend more angularly at joints as it swings. The string would clip through the top of the machine, which isn't a huge deal but it's a bit of a drawback if I want to zoom out from the machine at any time. Finally, it might give less control to have a three layer dependency between the mover box, the string, and the claw. Each would be based on the physics driven movement of it's parent, which could cause inaccuracies and glitches.
The second method is a bit of a workaround but may prove to be more reliable and give more control. The mover box, as the Pawn, has an invisible Physics Gun "weapon" that is always aimed downwards 90 degrees. This Physics Gun would be constantly firing, and traces to a specifically designated actor (the top bone of the claw.) This way, the movement of the claw is bound to the movement of the mover box, which is player controlled. The string is a soft body that is attached as a detail between the two at its two end joints. It is modeled to its shortest length and, because it's a soft body, will stretch to the extent that the claw is dropped.
I have been working with this method the most, and have got it mostly working. The things I'm figuring out right now are how to make the weapon constantly fire, and how to trace to one specific actor to ensure that the claw is the only mesh that is picked up by the mover box. The advantage of this method is again, the direct link between the mover box and the claw, removing the room for error of the string. Already implemented with the Physics Gun is the sway and interpolation of the object that is being grabbed. Additionally, I've found a modified version of the Physics Gun code that allows for a Push and Pull function that changes the hold distance between the Pawn and the object grabbed, which is essentially the claw drop. It can be bound to the scroll wheel of a mouse, which may be a more fun and interactive way for the player to handle claw drop (using the claw more like a wrecking ball than a static, timed drop.)