Asset Loading

In order to load an IMVU asset, you need to create a GameObject and put a LocalAssetLoader on it. If you want this loading to synchronize properly in a multiplayer experience, you'll also need a UNetAssetLoader or a PhotonAssetLoader, depending on whether you're using UNet or Photon for your network layer.

Each of these components has a Load function on it, which can take a UserModel, to load the user's default out, or an OutfitModel to load a saved outfit. It also has an optional second argument of type LoadOptions to specify level of detail, material types and animation settings.

You can derive from these components, or use them raw, whichever better suits your app's architecture.

Level of Detail

The API supports loading asset meshes at several different levels of detail and can set up loaded assets to automatically switch between them depending on the percentage of screen space that they occupy. This lets you display assets with dense meshes when close up, when detail is needed, but then switch to meshes with fewer triangles when at a distance, to improve drawing performance.

By default, they are configured to load each GameObject with several levels of detail and automatically switch between them, which has obvious benefits. However, there are cases when you may want to specify custom level-of-detail settings:

  • If you specify fewer levels of detail than the default, the load will make fewer network requests for mesh data, saving some loading time.
  • If you specify just one level of detail, the load can omit the LodComponent that does the automated switching between levels, saving some per-frame CPU overhead.
  • Custom settings also let you tune the default transition points for display quality or performance.

You can customize the default level of detail settings in the IMVU Settings window, or override the defaults at run time, in a way which can be optionally saved in the user's local store, as detailed in the Settings section of the documentation. You can also use the LoadOptions on a specific load call to override the settings for that load.

Custom level-of-detail settings are specified by a list of LodSetting objects. Each LodSetting object specifies a LodLevel and a maximum screen coverage percentage. There are four LodLevels available:

  • LodLevel.Maximum - The most detailed mesh, as originally authored.
  • LodLevel.Medium - An automatically generated mesh with lower detail (about 50%).
  • LodLevel.Low - An automatically generated mesh with very low detail (about 10%).
  • LodLevel.Hidden - Displays no meshes at all.

Note that the actual amount of detail reduction depends on the geometry of the mesh. For some models, reduction may not be possible, in which case the original mesh is used for all levels.

Screen coverage percentage is expressed as a float from 0-100. At runtime, the screen coverage is estimated from the bounding boxes of the meshes, and the level with the smallest coverage value greater than the object's current coverage (capped to 100%) is used. If you do not specify levels up to 100% coverage, the maximum level will be automatically included.

For example, if we were loading an asset that we know will never be displayed in detail, we could save some network bandwidth by omitting the maximum level when loading, using these LoD settings:

new List<LodSetting>() {
    new LodSetting(LodLevel.Hidden, 0.01f),
    new LodSetting(LodLevel.Low, 1.0f),
    new LodSetting(LodLevel.Medium, 100.0f),
}

Or, if we were loading an asset to only be displayed in detail, we could save some network requests and runtime CPU by loading just the maximum level, with these LoD settings:

new List<LodSetting>() {
    new LodSetting(LodLevel.Maximum, 100.0f),
}

Material Types

There are two different types of shaders available for the avatars:

  • Unlit - These are the simplest shaders. They have no lighting and no shadows. They will tend to be the fastest.
  • Lit - These shaders use the Unity legacy lighting system. They are lit and recieve and cast shadows.

You can customize the default material type settings in the IMVU Settings window, or override the defaults at run time, in a way which can be optionally saved in the user's local store, as detailed in the Settings section of the documentation. You can also use the LoadOptions on a specific load call to override the settings for that load.

Animations

IMVU avatars come bundled with a set of animations that are used in the IMVU ecosystem. These are divided into two groups: skeletal animations and morph animations.

  • Skeletal animations move the skeleton of the avatar or one of it's attachments, just like any normal Unity animation.

  • Morph animations apply offsets to the vertices of a mesh. They're used primarily for facial expressions, though they're occassionally used for a variety of other purposes as well. They're implemented here using Unity's blend shapes.

One of the load options that can be specified in the IMVU settings window or the LoadOptions is whether or not to load animations. If animations are loaded, then an ImvuAnimator will be added to the avatar, and each attachment, which can be used to manage those animations for that avatar or attachment. If you want to manage animations for the avatar and all it's attachments at once, use the functions on AssetInfo.

The avatar is completely Mecanim ready, so playing any humanoid animations through Mecanim should just work. However, if your animations want to control the avatar's facial morphs, this takes some extra doing. There is a component called the ImvuMorphAnimator you'll need to use. However, you can't just add this component to the avatar after it's loaded. It needs to be added to the GameObject in the editor, and the Animator with the correct RuntimeAnimatorController on it also needs to be there, so it has the opportunity to pre-calculate some data about the Mecanim state machine ahead of time. If these conditions aren't met, then the morph animations won't work.

Gaze

IMVU avatars have the ability to rotate their eyes to look at a specified target. This uses morphs (Unity's blend shapes), and thus can't be driven directly by Mecanim's built-in head IK system.

If you wish to utilize gaze, after the avatar is loaded add a GazeComponent to it, then call SetGazeTargetObject on it, passing in the GameObject you want the eyes to gaze at. This by itself will only cause the eyes to track the target. For best results, combine this with Mecanim head IK in order to make the head also track the target.