Deprecated: Creation of dynamic property wpdb::$categories is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 668

Deprecated: Creation of dynamic property wpdb::$post2cat is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 668

Deprecated: Creation of dynamic property wpdb::$link2cat is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 668

Deprecated: Return type of WP_Theme::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 554

Deprecated: Return type of WP_Theme::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 595

Deprecated: Return type of WP_Theme::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 535

Deprecated: Return type of WP_Theme::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 544

Deprecated: Return type of WP_REST_Request::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 960

Deprecated: Return type of WP_REST_Request::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 980

Deprecated: Return type of WP_REST_Request::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 992

Deprecated: Return type of WP_REST_Request::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 1003

Deprecated: Return type of WP_Block_List::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 151

Deprecated: Return type of WP_Block_List::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 175

Deprecated: Return type of WP_Block_List::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 164

Deprecated: Return type of WP_Block_List::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 186

Deprecated: Return type of WP_Block_List::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 138

Deprecated: Return type of WP_Block_List::offsetExists($index) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 75

Deprecated: Return type of WP_Block_List::offsetGet($index) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 89

Deprecated: Return type of WP_Block_List::offsetSet($index, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 110

Deprecated: Return type of WP_Block_List::offsetUnset($index) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 127

Deprecated: Return type of WP_Block_List::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 199

Deprecated: Creation of dynamic property Automattic\Jetpack\Connection\Manager::$error_handler is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/vendor/automattic/jetpack-connection/src/class-manager.php on line 91

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Instagram_Gallery::$is_wpcom is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-instagram-gallery.php on line 23

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Mailchimp::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-mailchimp.php on line 17

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Tweetstorm_Gather::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-tweetstorm-gather.php on line 21

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Tweetstorm_Gather::$is_wpcom is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-tweetstorm-gather.php on line 22

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Gutenberg_Available_Extensions::$wpcom_is_site_specific_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/gutenberg-available-extensions.php on line 20

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Memberships::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/memberships.php on line 23

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Memberships::$wpcom_is_site_specific_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/memberships.php on line 24

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Subscribers::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/subscribers.php on line 15

Deprecated: Creation of dynamic property Automattic\Jetpack\Sync\Queue::$random_int is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/vendor/automattic/jetpack-sync/src/class-queue.php on line 38

Deprecated: Creation of dynamic property Automattic\Jetpack\Sync\Queue::$random_int is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/vendor/automattic/jetpack-sync/src/class-queue.php on line 38

Deprecated: Creation of dynamic property WPCOM_Widget_Goodreads::$shelves is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/modules/widgets/goodreads.php on line 33

Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /var/www/twodee/blog/wp-includes/script-loader.php on line 348

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_classic_block is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 347

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_block is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 349

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_block_side is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 350

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$panels_block is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 351

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$used_block_buttons is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 354

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198
» CS 491 Lecture 14 – Animation

teaching machines

CS 491 Lecture 14 – Animation

March 29, 2016 by . Filed under
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
gamedev3, lectures, spring 2016.

TODO

Lab

Today we explore Unity’s animation tools. Let’s define animation as the changing of an object’s properties over time. In fact, we’ve already looked at a few animation techniques:

Our vehicle for changing these properties has been code. Today, our vehicle will be Unity’s builtin animation system. We will write no code.

Instead of altering properties in code, we will manually set an object’s properties in the Inspector, but these properties will be triggered at certain times in our object’s lifespan. We call these times keyframes. Between keyframes, Unity will automatically interpolate or tween the property’s values.

Animated properties don’t have to be spatial. We can animate colors, a component’s enabled status, texture coordinates, and pretty much any property that can represented as a number or boolean. But animating ints and booleans is a little different than animating floats. Why? Discuss this question aloud with your partner.

FPSController and Platforms

We’re going to create a gallery of independent animations today. Let’s organize our gallery into separate platforms. Our first animation will go on platform 1, our second on platform 2, and so on. Add a cube object and scale it (10, 1, 10). We can duplicate this starting platform later.

Also add an FPSController and position it over your first platform.

Playtest. Can you walk around in the platform?

Dark World

Let’s make this game world dark. For our first animation, we’ll toggle the default directional light on and off for a suspenseful strobe effect.

First, to make the world dark, we need to adjust a few things. Go to Window / Lighting, and set the Skybox to None and the Ambient Intensity to 0. Ambient lighting is the baseline “lightedness” of our scene. It is computed without regard to any lights and without any involved mathematical equations. Even if no lights are in the scene, the intensity represents what proportion of a surface’s color still reaches your eye. Ambient lighting is a cheap hack for making it look like light bounces around your scene (which it does not do). In this case, we want no color to reach our eyes when the light is off, so ambient lighting has to go.

Playtest. Toggle the enabled checkbox of the directional light. Does the scene go dark?

We also need to darken the camera background. Find your FPSController’s Camera component and set its Background to black.

Playtest. Toggle the directional light. Is that darker?

Animating Light Enabled

Now let’s animate toggling the light.

In the project assets, create an animator controller. We’ll be making several of these, so give it a meaningful name, like Sun Animator Controller. Drag it onto the directional light. Unity automatically creates an Animator component, which we will not be concerned with today.

Open the Animation window. (There are several Animat* windows listed in the Window menu. Be precise.) Select the Directional Light. You should see a Create button in the Animation window. Click this button and name the animation Strobe.

For all our animations, we’ll follow the procedure just described, which I’ll refer to later as the animation workflow. I’ll condense it into a recipe:

  1. Create an animator controller for the object you wish to animate.
  2. Drag the controller onto the object you wish to animate, upon which Unity automatically adds an Animator component.
  3. Select the object.
  4. Create an animation clip by clicking Create in the Animation window.

In the Animation window you see what’s called a dopesheet. On the y-axis is the property being animated. On the x-axis is time. The dopesheet shows when keyframes have been established and for what properties. It doesn’t generally show you the value for those keyframes.

Let’s add some keyframes for our enabled property. Click Add Property / Light / Enabled. Click on the plus sign to insert an initial keyframe. By default, the light is enabled. Click or scrub the mouse through the timeline at the top and position the cursor at 2:00 (which is 2 seconds). Disable the light in the Inspector. A new keyframe is automatically recorded.

This automatic recording can be kind of dangerous. If you alter a property of an animated object, even if that property isn’t yet animated, the change will insert a keyframe, which may not be your intention. (This happens to me especially with Transform. Every time I move an object, I inadvertently add a keyframe!) You can turn off automatic recording by clicking the red circle button at the top left of the Animation window.

Playtest. Does the light turn on and off?

Probably not. The problem is that our animation finishes after the last keyframe and then starts over. There’s only a brief instant where the light is disabled. You can visualize this by clicking on the Curves button at the bottom of the window. This view shows how a property is interpolated between keyframes. The property stays high except for a little blip down at 2:00.

To fix this, let’s add a third keyframe at 4:00 with the light enabled. Do this back in the dopesheet. Check your work in the Curves editor. This part will come up a lot when alternating between two values. Let’s call this pattern the three-key sandwich.

Playtest. Is it suspenseful?

Animating Light Color

Let’s add a second light source and animate it’s color. Add a point light and position if very close to the platform. Follow the animation workflow and give it an animation clip named BlueRed.

Add a keyframe for the light’s color via Add Property / Light / Color. Scrub to 0:00, and set the light’s color to blue in the Inspector. Scrub to 3:00 and set it to red. And don’t forget we need one more keyframe to give the light time to be red. Scrub to 6:00 and set the light to blue.

Playtest. How does it look?

Animating Rising Platform

Duplicate your platform and place it near but not touching the first. We’re going to make this platform cycle up and down forever. Follow the animation workflow and create a Elevate clip.

Instead of clicking Add Property / Transform / Position, just make sure autorecording is on and that you are scrubbed to time 0. Lower the platform on the y-axis.  Scrub to 2:30. Raise the platform’s on the y-axis.

Scrub to 5:00. We want this last keyframe to match the first exactly. If we don’t, we’ll get a hiccup in our animation. To ensure an exact match, let’s copy the first keyframe. Select the top diamond at the first keyframe, which will select all the property values. Hit Control-C or Command-C to copy. Scrub to 5:00. Hit Control-V or Command-V to paste.

Playtest. Does the platform raise and lower?

The only trouble is the abruptness we see at the trough of our animation. Let’s smooth that out a bit. Go to the Curves view. You should be able to see the discontinuity on the green y curve. The peak is nice and smooth, but not the trough. Select the first keyframe. Right-click and select Flat. Do the same for the last keyframe.

Playtest. Is that smoother?

Animating Multiple Linked Properties

Add a third platform. Place a sphere on it. Let’s have it blink in and out of existence. Follow the animation workflow and create a Blink clip.

Add a three-key sandwich that toggles the sphere’s Mesh Renderer’s enabled property.

Playtest. Does the sphere appear and disappear? Try running into the sphere when it’s invisible.

Unfortunately, though it visually disappears (a Renderer is something that affects the display), the physics system still recognizes the sphere’s existence. Add a second three-key sandwich for the sphere’s collider’s enabled property, making sure the collider is disabled when the Mesh Renderer is.

Playtest. Can you run freely through the invisible sphere?

As you have just seen, a single animation clip can animate multiple properties.

Animating Spotlight

Let’s animate a searching spotlight. Add a fourth platform. Place above it a spotlight pointing straight down at the platform. Then rotate it on the x-axis a bit so it’s not pointing exactly straight down.

Follow the animation workflow to create a Search clip. Scrub to 0 and click Add Property / Transform / Rotation. At 1:00, add a second keyframe where the y rotation angle is 360 degrees more than the first keyframe.

Playtest. How does that look?

Let’s try seeing this animation under different interpolation schemes. Click on Curves. Set both keyframes to be flat. Playtest. How does that look? Probably terrible. For rotations like this, which are not a three-key mirror, we general don’t want easing. For translation, we often do want easing because it’s more realistic. We slow down when we change directions.

Right-click on both keyframes and select Both Tangents / Linear to switch to linear interpolation. Playtest. Is that better?

Animating Texture

Let’s animate a scrolling texture on a platform. Add a fifth platform. Create a new Material in your project assets. Import a seamless texture. I like this one from Jaromir Sivic:

Drop this image into the albedo slot of your Material. Drop the Material on to your new platform.

You may want to disable the Directional Light’s Animator. It’s kind of distracting.

Playtest. Can you see the texture on the platform?

Now let’s have it scroll across the platform. We do this by animating the Material’s texture coordinates, which map the 3D vertices to pixel locations in our texture. Follow the animation workflow to create a clip named Scroll.

Select the platform and scrub to 0. Click Add Property and look at the Mesh Renderer / Material properties. What property do we want to animate? I wasn’t exactly sure, so I just went to the Inspector and altered the x-offset under Main Maps. This established the initial keyframes I wanted. Do this, but set the x-offset back to 0. Scrub to a later time. Set the x-offset to 1.

Playtest. Does the water scroll across the platform?