# Part of the body

> The legs keep running while the arms wave: a second animator on the same model, told which bones are its own with only.

Example `gltf-body-parts`, running at https://nacatamalon.com/en/examples/gltf-body-parts. The whole catalogue: https://nacatamalon.com/llms/examples.md.

The legs keep running while the arms wave. A second animator on the same model is told which bones are its own with `only`, and goes on top of the first.

A bone comes with everything that hangs from it, so `'spine'` is the chest, the head and both arms. When its movement ends it hands the bones back, eased by its `fade`, without anybody asking.

Click the preview first so it hears the keyboard. Space waves, 1 or 2 change what the legs are doing.

## Code

`index.ts`:

```ts
import { createGame } from 'nacatamalon';
import { WIDTH, HEIGHT } from './settings';
import { Level } from './scenes/demo';

const game = createGame('#app', {
    width: WIDTH,
    height: HEIGHT,
    background: '#10131c'
});

// Declare Scenes
game({
    Level
});
```

`components/character.ts`:

```ts
import { createModel, useKeyboard, useLoadModel, useSkeletalAnimation, useUpdate } from 'nacatamalon';
import * as Settings from '../settings';

export const Character = () => {
    const mixer = createModel({
        model: useLoadModel(Settings.MODEL)
    });

    const legs = useSkeletalAnimation(mixer, {
        play: 'run',
        fade: Settings.BODY.fade
    });

    const top = useSkeletalAnimation(mixer, {
        only: [Settings.BODY.spine],
        fade: Settings.BODY.upperFade,
        clips: {
            greet: {
                loop: false
            }
        },
    });

    const keys = useKeyboard();

    useUpdate(() => {
        if (keys.justPressed('Space')) {
            top.play('greet');
        }

        if (keys.justPressed('1')) {
            legs.play('run');
        }

        if (keys.justPressed('2')) {
            legs.play('walk');
        }
    });
};
```

`scenes/demo.ts`:

```ts
import { createScene, useCamera3d, useDirectionalLight, useSpawn } from 'nacatamalon';
import * as Settings from '../settings';

import { Character } from '../components/character';

export const Level = () => {
    useCamera3d(Settings.CAMERA);
    useDirectionalLight({
        color: '#fff2e0',
        intensity: 1.1,
        ambient: 0.4,
        transform: {
            rotationX: -0.5,
            rotationY: 0.5
        }
    });

    useSpawn(Character)();

    return createScene();
};
```

`settings.ts`:

```ts
export const WIDTH = 480;
export const HEIGHT = 360;
import type { TCamera3dOptions } from 'nacatamalon';

export const CAMERA = {
    projection: 'perspective',
    fov: 40,
    transform: {
        y: 5.5,
        z: 20
    }
} satisfies TCamera3dOptions;
export const MODEL = {
    src: '/example-assets/assets/3d/gltf/Mixer/mixer.glb'
};
export const BODY = {
    fade: 0.3,
    spine: 'spine',
    upperFade: 0.25
};
```
