Introduction to Python in MotionBuilder – Part 2: Animating a Camera’s Aim with Constraints


Now that we’ve populated our scene, let’s animate the camera’s aim from the cube to the sphere. We can achieve this animation in a variety of ways. One way would be to keyframe the rotation property of the camera. Another way would be to assign an interest point to the camera, and move that point from the cube to the sphere. However, using either of these approaches, if we change the position of the cube or the sphere, we would need to create a new set of keys on either the camera or its interest point. Instead, we’ll animate the camera’s aim using two weighted aim constraints. The first aim constraint will constrain the camera’s aim towards the cube. The second aim constraint will constrain the camera’s aim towards the sphere. As time advances, the weight of the first constraint will decrease, while the weight of the second constraint will increase. To create our aim constraints, we’ll use the FBCreateObject() function. In the Asset Browser, the aim constraint is located under Templates, Constraints. If we run the script now, the constraints don’t appear in the Scene Browser. We need to explicitly add these constraints into the scene. To do that, we’ll need a reference to the FBScene object contained in FBSystem().Scene Use the scene.Constraints.append() function to add aim1 and aim2 into the scene. If we run the script now, the constraints are visible in the Scene Browser. We now have to apply the constraints to the objects in the scene. If we were doing this through the user interface, we would Alt-click and drag the camera into the first constraint’s “Constrained Object” field. Likewise, we would alt-click and drag the cube into the “Aim At Object 1” field. The constraint would therefore constrain the camera’s aim to the cube. Before we do this with our script, we’ll need a bit more information about the FBConstraint class. aim1 and aim2 are instances of the FBConstraint class. The “Constrained Object” and “Aim at Object” fields are known as the constraint’s “Reference Groups”. In the Python API documentation, a variety of methods of FBConstraint deal with Reference Groups. These methods let you check how many reference groups there are in a constraint, and let you add or remove objects to and from these reference groups. To make sure we know which name to use, we’ll print out some information about the first constraint’s reference groups. When we run the script, the constraints’ reference groups are empty, since we had cleared the scene at the beginning of the script. Other constraint types have different reference group names, but in this case, we’re interested in adding the camera to the “Constrained Object” reference group. We also want to add the cube to the “Aim at Object” reference group. To streamline this process, we’ll create a helper function called “setConstraintReferenceByName”. This function iterates over the constraint’s reference groups, and adds the model to the appropriate reference group index, via the ReferenceAdd() function. Call setConstraintReferenceByName() using the aim1 constraint, and set the camera as the “Constrained Object”. Call setConstraintReferenceByName() using the aim1 constraint, but this time set the cube as the “Aim At Object”. Set the constraint’s Active property to True to constrain the camera. When we run the script, the first aim constraint will have its fields populated, and the camera will now aim towards the cube. Repeat the same process with the aim2 constraint, using the sphere as the “Aim At Object”. For now, we’ll set the Weight property of aim2 to 0, to keep the camera pointing towards the cube. Inform MotionBuilder that the Weight property of both constraints is animatable, via SetAnimated( True ) By calling this function, we are initializing the Weight property’s “Animation Node”. An “Animation Node” stores the animation information of a property. To retrieve the weight’s Animation Node, call GetAnimationNode(). To key a weight value of 100, first call SetCandidate( [100] ). A constraint’s weight is expressed as a single number, or as a one-dimensional vector, which is why we place the value of 100 in a list of size 1. To key this value at frame 0, call KeyCandidate() with an FBTime object describing the time at hour 0… minute 0… second 0… and frame 0. Next, key a weight value of 0 at frame 60. Following the same approach, we’ll animate the weight of the second constraint, as it goes from 0 to 100 during the same 60 frame interval. When we run the script now, the camera’s aim shifts from the cube to the sphere between frame 0 and frame 60. You should now have a good idea of how to use Python to create and animate objects in MotionBuilder.

Leave a Reply

Your email address will not be published. Required fields are marked *