6. Completing the Brief

After much deliberation and the implementation of many different methods, ranging from particles to instancing geometry and actually using geometry, as well as having the choice of writing it in a script or using expressions to dynamically change the attributes, I had finally arrived at a possible solution.

 First of all I had to fulfil the brief, which was:

Mud Direction

These were my two challenges. To begin with I had to get the geometry to follow some sort of point or orient towards a destination. 

My first version of mudmanTroop_v1 was just a simple script. Because of the nature of the troop they would be walking in unison and have an almost army like feel to them. Thus I used a simple expression at the beginning which just made the objects translate in the x direction uniformly, so the geometry just moved forward over time. This was not really direction specific but it brought me closer to my goal.

Next I implemented the solution I had for the animation with using a simple expression on the blendhapes envelope value. My script was beginning to take shape. When I pressed the magical return button I got a reaction, not an error. This was a move in the right direction for me!

However I didn’t think it had quite the functionality that I needed plus if I gave the script to anyone else they’d have quite a bit of a problem just executing it.

I needed to build in some more complexity.

Just a generic transform in the x direction was no good. I realised I would certainly have to change that. So how could I constrain the objects but not have them all have the same position? Scouring the Mel command reference I came across the PointConstraint command, which as the name says constrains any object selected to the first object selected.

For this to work I would have to use a simple for loop to loop through the selected objects-(Mud Men troop)- and assign the PointConstraintt to the objects. I found when using the Mel command PointConstraint that it set the default values of the geometry to 0 0 0, which meant that all the objects, no matter how dynamically  -or un-dynamically, as the case might be- I had placed the objects it just reset them to the default position. So just iterating through the objects and then assigning the PointConstraint command was no good. I would have to come up with a method of my own which would not reset my values.

I found that if I just grouped all the objects then assigned them to the locator with the PointConstraint command that they then were autonomous but still followed the locator. This meant that I could now keyframe the locator wherever I wanted the troop to go. I still didn’t like how constricting the PointConstraint command was so I decided to ditch it for simpler expressions, which I had far more control over.

All I did to achieve this was to put an extra procedure in the script which first grouped the objects and then constrained the group to a locators x y and z values. This left me with a couple of additional problems.

Looking Mud

I could now make them go in any direction but the of course didn’t orient themselves towards their goal, they just faced forward in the x direction. This meant that they slid as soon as I started moving the locator in two different directions x and z. So how was I to solve this? Once again I turned towards the Mel commands reference, which pointed me towards the aimConstraint command. This would again basically do the hard work for me.

 This command however worked in reverse to the PointConstraintt. Simply applying it to the group would result in the aimConstraint falling down. I would have to iterate through the elements in the selected array of objects and apply the aimConstraint individually to each object.

 Now I actually had a lot of problems with these different methods. Iterate does not iterate. There were loads of problems with passing the values of the data types. It took a bit of fiddling but it worked in the end. Of course once the aimConstriant was set in place it was joined to the locator, which meant the troop all looked at the locator but when the locator moved so did the troop. This meant their focus of attention never left the centre of the troop. As the troop moved so did the aimConstraint, and for me this was absolutely useless. I would have to find another way to do it.

 I figured that I could constrain the actual rotate values of each object with the rotate values of each object. This worked to an extent on the x and z values, but if I constrained the y value they each rotated upwards autonomously to each other which as you can imagine would not work right within the group .

 The best way to do it was to constrain the entire group’s rotate y value to the rotate value of the locator, giving complete control. Now I had objects that moved in the direction of a locator and oriented themselves towards that locator too. Part of the way there!

Easy Mud

 Next I wanted make it more user friendly, seeing as it was actually being written for my brother to implement in his project. Given the fact that he had a limited knowledge of  Maya I couldn’t exactly give him just the script and say “There you go, Chris, all you need to do is blah blah .”  So for functionality I would have to learn to use GUI in Maya.

 I never realised before how hard it was to actually capture a value that had been imputed. Unless I’m really stupid or looking at things upside down, it seemed so hard to just capture a value, and then use it in the script. Basically all I wanted to allow my user to do was to be able to choose the amount of geometry that they wanted and then to be able to simply click the button and everything would work. Instant script for an army of Mud Men!

 I set an expression that manipulated the envelope attribute of a blendshape for ease of compatibility. This meant that I needed the objects to all have the blendshape attribute. The only way to do this was to instance the object but make it world space and don’t parent it. Then all I’d need to get was a variable that would stand as the amount by which to iterate the instance command.

 This brought it’s own problems! Once again I had to learn everything I could about GUI’s because I had a limited knowledge of GUI’s. This was a completely new experience and perhaps that’s why I struggled with it quite a bit. However on a positive note I can’t help but comment that it brought a lot of fun to the whole exercise. I found I could call the window MuddyWindow, have an input that asks ‘how much mud?’ or have a button with ‘let’s get muddy!’ on it!

 Finished Mud

 All that was left was to put it together so that the script executed all the commands with just one button press.

I decided to use functions as blocks to make up the program. It also allowed for better error checking because I could usually find the root of the problem with little trouble. This made fixing bugs a little easier.

 My script executes at the button press of the GUI. It then calls mixUpMud proc which creates the Mud Men, or you could throw mud x and throw mud z, which allows for a more uniform troop. Then there is a separate button for the TROOPFALL_IN which starts the main loop which calls the smaller functions Mud MenLook and Mud MenMove that constrain the objects to the locator.

Random Mud Creation

Uniform Mud Creation

Breakdown

The end result is a nice behavioural system that is easy to implement.