Code samples

How to create and load a didimo

To load a didimo into a custom scene you need simply to have a DidimoImporter script attached to a GameObject in the scene, fill in the placeholder GameObject reference where to instantiate the didimo at, and then call the ImportDidimo method passing in the didimo key, template version, and metadata.

The sample code below shows a call that creates a didimo, then requests the definition model, and then downloads and instantiates the didimo in the active scene.

ServicesRequests.GameInstance.CreateDidimoCheckProgress(
                coroutineManager,
                snap,
                "",
                (didimoKey) =>
                {
                    LoadingOverlay.Instance.ShowLoadingMenu(() =>
                    {
                        coroutineManager.StopAllCoroutines();
                    }, "Downloading...");


                    ServicesRequests.GameInstance.GetDidimoDefinitionModel(
                        coroutineManager,
                        didimoKey,
                        (didimoDefinitionModel) =>
                        {
                            mainMenu.DidimoImporter.ImportDidimo(coroutineManager, didimoKey, didimoDefinitionModel.meta,
                                didimoGameObject =>
                                {
                                    Debug.Log("Didimo loading is complete!");
                                    LoadingOverlay.Instance.Hide(); 
                                    if (mainMenu != null)
                                    {
                                        mainMenu.HideMenu();
                                        mainMenu.InitPlayerPanel(didimoGameObject, didimoKey,  didimoDefinitionModel.meta); 
                                    }
                                },
                                exception =>
                                {
                                    ErrorOverlay.Instance.ShowError(exception.Message);
                                }
                            );
                        },
                        exception =>
                        {
                            ErrorOverlay.Instance.ShowError(exception.Message);
                        }
                    );
                },
                exception =>
                {
                    ErrorOverlay.Instance.ShowError(exception.Message);
                },
                progress =>
                {
                    LoadingOverlay.Instance.ShowProgress(progress);
                });

The User Interface of the sample scene is mostly managed by the DidimoMenuHandler script, which sets up the UI according to template version and supported features.

public void InitPlayerPanel(GameObject didimoGameObject, string didimoCode, List<DidimoMetadataDataObject> metadata)
        {
            bool isDeformationSupported = DidimoAvatarDataObject.IsDeformationSupported(metadata);
            bool isExpressionSupported = DidimoAvatarDataObject.IsExpressionSupported(metadata);
            bool isBasicRigSupported = DidimoAvatarDataObject.IsBasicRigSupported(metadata);
            bool isRealtimeRigSupported = DidimoAvatarDataObject.IsRealtimeRigSupported(metadata); //this is actually the same as expressions support
            bool isTextToSpeechSupported = DidimoAvatarDataObject.IsTextToSpeechSupported(metadata);

            shouldDisplayHairScroller = true;
            animButtonsPanel.SetActive(true);

            ////Setup UI
            //init hair
            hairConfig.InitHairList(didimoCode);
            togglesHandler.EnableHairOption();

            
            //init idles 
            togglesHandler.EnableIdlesPlayer(isExpressionSupported);

            //init other scrollers
            //eye, haircolor, mocap
            togglesHandler.EnableEyesConfigOption();
            eyesScroller.InitializeEyesGalleryScroller();

            //init hair color
            togglesHandler.EnableHairColorOption();
            hairColorScroller.InitializeHairColorGalleryScroller();
            hairColorScroller.onItemToggleEventDelegate = (toggle, toggled_index, materialState) => {
                if (toggle.isOn)
                {
                    //Debug.Log("SetHairColorAtIndex " + toggled_index);
                    hairConfig.ChangeHairColorToIndex(toggled_index, materialState);
                }
            };

            ///Load animation system
            if (isBasicRigSupported || isRealtimeRigSupported || isExpressionSupported || isTextToSpeechSupported) //isTextToSpeechSupported
            {
                //realtimerig
                LoadingOverlay.Instance.ShowLoadingMenu(() => { }, "Setting up the animation system");

                AnimationPlayer animPlayer = didimoGameObject.GetComponentInChildren<AnimationPlayer>(true);
                animManager.animPlayer = animPlayer;
                animPlayer.interpolateBetweenFrames = false;

                //mocap  
                FileInfo[] objectlist = new FileInfo[0];
                List<string> jsonAnimationTracks = new List<string>();
                //basic rig is supported by both
                //sample animations - to show the amplitude of the supported animation
                jsonAnimationTracks.Add("DidimoImporter/2.0/AnimationFiles/DefaultMocap/simpleROM");
                jsonAnimationTracks.Add("DidimoImporter/2.0/AnimationFiles/DefaultMocap/faceROM");
                //if full range of motion (facial expression) is not supported by the loaded didimo we might need to display a anim-rig mismatch warning when playing such animations
                //init mocap items scroller UI
                mocapScroller.onItemToggleEventDelegate = (toggle, toggled_index) => {
                    StartCoroutine(PlayMocapAtIndex(toggle.GetComponent<Toggle>(), toggled_index, isBasicRigSupported));
                };
                mocapScroller.InitializeMocapRecordingsGalleryScroller(objectlist, jsonAnimationTracks.ToArray());
                //also init the mocap player
                animManager.SetDefaultAnimationTracksFromPathList(jsonAnimationTracks);
                animManager.Refresh();
                animPlayer.PauseAnimations(true); //the animation player update should not be running when starting
                //enable option on the user interface
                togglesHandler.EnableMocapOption();

                if (isTextToSpeechSupported)
                {
                    speechManager.RealtimeRig = didimoGameObject.GetComponent<Didimo.RealtimeRig.Animation.RealtimeRig>();
                    togglesHandler.EnableSpeechOption();
                }
                else {
                    speechManager.RealtimeRig = null;
                    togglesHandler.DisableSpeechOption();
                }

            }
            else
            {
                Debug.Log("Current didimo has no animation support!");
            }
            LoadingOverlay.Instance.Hide();
            pauseToggle.SetIsOnWithoutNotify(false);
            hasDidimoBeenLoaded = true;
        }

NOTE:
These steps will also allow you to load a Didimo into a full body character, but beforehand you will need make sure that:

  • The head of the character is in a separate mesh. To make this easy, you can pick a Didimo generated from our pipeline, and “stitch” it into the body of a character. You can download a FBX version of the didimo zip package which can be used for this purpose.
  • The head is rigged by our skeleton. You can insert it as part of another skeleton (e.g. put our root bone in the neck bone of your full body character).
  • By default, we do not include a full body character scene in our sample package. If this scene is of your interest to check it out, please email us.

Last updated on 2020-10-06