void Start()
    {
        Screen.fullScreen  = false;
        Screen.orientation = ScreenOrientation.Portrait;

        AppSocket.SetOnReceiveHandler(OnReceive);

        if (!AvatarSdkMgr.IsInitialized)
        {
            AvatarSdkMgr.Init();
        }

        avatarProvider = AvatarSdkMgr.IoCContainer.Create <IAvatarProvider>();
        QualitySettings.antiAliasing = 2;

        AppSocket.SendCommand(AppSocket.SendType.UNITY_LOADED);

        if (Application.platform != RuntimePlatform.Android)
        {
            QualitySettings.antiAliasing = 8;
            String marcoBody      = "mech_ferrari";
            String marcoAvatar    = "3907ed35-7071-4ed1-b242-169cb3abc237";
            String marcoHair      = "male_NewSea_J082m";
            String marcoHairColor = "#3E271F";

            String paolaBody      = "sport_female_m";
            String paolaAvatar    = "7d910c92-b62c-4084-8f42-749a2cb94eb2";
            String paolaHair      = "female_NewSea_J096f";
            String paolaHairColor = "#202020";

            String aliceBody      = "medic_female";
            String aliceAvatar    = "063f8e92-4675-4bee-8f4f-a303779b4e3c";
            String aliceHair      = "female_NewSea_J123f";
            String aliceHairColor = "#3E271F";


            if (playerObj != null)
            {
                CreateAvatar("b7ce00b9-3589-4dbd-9b5b-2466233e9d89", paolaAvatar, paolaHair, paolaHairColor);
            }
            else
            {
                CreateAvatar("b7ce00b9-3589-4dbd-9b5b-2466233e9d89", marcoBody, marcoAvatar, marcoHair, marcoHairColor);
            }
        }
    }
    private static IEnumerator Speech(GameObject avatar, string fullPath)
    {
        AudioSource audioSource = avatar.GetComponent <AudioSource>();

        if (fullPath != null && fullPath.Trim().Length > 0)
        {
            AudioClip audioClip = null;

            // Application.temporaryCachePath = /storage/emulated/0/Android/data/it.unitn.robertonegro.facetoface/cache
            // using (WWW www = new WWW("file://" + Application.temporaryCachePath + "/" + fileName))

            using (WWW www = new WWW(fullPath))
            {
                while (!www.isDone)
                {
                    yield return(null);
                }

                if (www.error != null)
                {
                    Debug.LogError("Error loading file!");
                }
                else
                {
                    audioClip = www.GetAudioClip(true, false, AudioType.MPEG);
                }
            }

            if (audioClip != null)
            {
                audioSource.clip = audioClip;
                audioSource.Play();
                AppSocket.SendCommand(AppSocket.SendType.SPEECH_START, fullPath);
                yield return(new WaitForSeconds(audioClip.length));

                AppSocket.SendCommand(AppSocket.SendType.SPEECH_FINISH, fullPath);
            }
        }
        else
        {
            audioSource.Pause();
        }
        yield break;
    }
    private void OnReceive(AppSocket.ReceiveType receiveType, params string[] parameters)
    {
        Debug.Log("Received command: " + receiveType.ToString());

        switch (receiveType)
        {
        case AppSocket.ReceiveType.BG_COLOR:
            if (parameters.Length != 1 || !SetBackgroundColor(parameters[0]))
            {
                AppSocket.SendCommand(AppSocket.SendType.ERROR_PARAMS);
            }
            break;

        case AppSocket.ReceiveType.AVATAR_REMOVE:
            Destroy(playerObj);
            playerObj = null;
            break;

        case AppSocket.ReceiveType.ANIM_RUN_TRUE:
            AnimRunning(playerObj, true);
            break;

        case AppSocket.ReceiveType.ANIM_RUN_FALSE:
            AnimRunning(playerObj, false);
            break;

        case AppSocket.ReceiveType.ANIM_GREETINGS:
            AnimGreetings(playerObj);
            break;

        case AppSocket.ReceiveType.AVATAR_CREATE:
            if (parameters.Length != 5)
            {
                AppSocket.SendCommand(AppSocket.SendType.ERROR_PARAMS);
            }
            else
            {
                CreateAvatar(parameters[0], parameters[1], parameters[2], parameters[3], parameters[4]);
            }
            break;

        case AppSocket.ReceiveType.CAMERA_TARGET:
            if (parameters.Length != 1)
            {
                AppSocket.SendCommand(AppSocket.SendType.ERROR_PARAMS);
            }
            else
            {
                SetCameraTarget(parameters[0]);
            }
            break;

        case AppSocket.ReceiveType.CAMERA_ANGLE:
            if (parameters.Length != 1)
            {
                AppSocket.SendCommand(AppSocket.SendType.ERROR_PARAMS);
            }
            else
            {
                SetCameraAngle(parameters[0]);
            }
            break;

        case AppSocket.ReceiveType.CAMERA_DISTANCE:
            if (parameters.Length != 1)
            {
                AppSocket.SendCommand(AppSocket.SendType.ERROR_PARAMS);
            }
            else
            {
                SetCameraDistance(parameters[0]);
            }
            break;

        case AppSocket.ReceiveType.CAMERA_HEIGHT:
            if (parameters.Length != 1)
            {
                AppSocket.SendCommand(AppSocket.SendType.ERROR_PARAMS);
            }
            else
            {
                SetCameraHeight(parameters[0]);
            }
            break;

        case AppSocket.ReceiveType.SPEECH:
            if (parameters.Length != 1)
            {
                AppSocket.SendCommand(AppSocket.SendType.ERROR_PARAMS);
            }
            else
            {
                StartCoroutine(Speech(playerObj.transform.Find("Avatar").gameObject, parameters[0]));
            }
            break;

        case AppSocket.ReceiveType.TEST:
            CreateAvatar("34fab30e-dd0b-4c38-bf43-86360c348db5", "sport_male_m", "c969ecd1-eb27-418c-a26c-1395cb01abbf", "male_makehuman_short02", "#222");
            break;

        default:
            break;
        }
    }
    private void FinishAvatar()
    {
        GameObject          avatar = playerObj.transform.Find("Avatar").gameObject;
        GameObject          head   = avatar.transform.Find("HeadObject").gameObject;
        SkinnedMeshRenderer skinnedMeshRenderer = head.GetComponent <SkinnedMeshRenderer>();

        // Add audio source to player for speaking sound
        AudioSource audioSource = avatar.AddComponent <AudioSource>();

        OVRLipSyncContext ovrContext = avatar.AddComponent <OVRLipSyncContext>();

        ovrContext.audioSource = audioSource;
        ovrContext.audioMute   = false;

        OVRLipSyncContextMorphTarget ovrMorphTarget = avatar.AddComponent <OVRLipSyncContextMorphTarget>();

        ovrMorphTarget.skinnedMeshRenderer = skinnedMeshRenderer;

        ovrMorphTarget.VisemeToBlendTargets[0]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("sil");
        ovrMorphTarget.VisemeToBlendTargets[1]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("pp");
        ovrMorphTarget.VisemeToBlendTargets[2]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("ff");
        ovrMorphTarget.VisemeToBlendTargets[3]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("TH");
        ovrMorphTarget.VisemeToBlendTargets[4]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("dd");
        ovrMorphTarget.VisemeToBlendTargets[5]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("kk");
        ovrMorphTarget.VisemeToBlendTargets[6]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("CH");
        ovrMorphTarget.VisemeToBlendTargets[7]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("ss");
        ovrMorphTarget.VisemeToBlendTargets[8]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("nn");
        ovrMorphTarget.VisemeToBlendTargets[9]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("rr");
        ovrMorphTarget.VisemeToBlendTargets[10] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("AA");
        ovrMorphTarget.VisemeToBlendTargets[11] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("EE");
        ovrMorphTarget.VisemeToBlendTargets[12] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("IH");
        ovrMorphTarget.VisemeToBlendTargets[13] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("OH");
        ovrMorphTarget.VisemeToBlendTargets[14] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("OU");

        ovrMorphTarget.KeySendVisemeSignal     = new int[15];
        ovrMorphTarget.KeySendVisemeSignal[0]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("sil");
        ovrMorphTarget.KeySendVisemeSignal[1]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("pp");
        ovrMorphTarget.KeySendVisemeSignal[2]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("ff");
        ovrMorphTarget.KeySendVisemeSignal[3]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("TH");
        ovrMorphTarget.KeySendVisemeSignal[4]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("dd");
        ovrMorphTarget.KeySendVisemeSignal[5]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("kk");
        ovrMorphTarget.KeySendVisemeSignal[6]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("CH");
        ovrMorphTarget.KeySendVisemeSignal[7]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("ss");
        ovrMorphTarget.KeySendVisemeSignal[8]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("nn");
        ovrMorphTarget.KeySendVisemeSignal[9]  = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("rr");
        ovrMorphTarget.KeySendVisemeSignal[10] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("AA");
        ovrMorphTarget.KeySendVisemeSignal[11] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("EE");
        ovrMorphTarget.KeySendVisemeSignal[12] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("IH");
        ovrMorphTarget.KeySendVisemeSignal[13] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("OH");
        ovrMorphTarget.KeySendVisemeSignal[14] = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("OU");

        ovrMorphTarget.SmoothAmount = 10;

        ovrContext.enabled = false;
        ovrContext.enabled = true;

        EyeController eyeController = avatar.AddComponent <EyeController>();

        eyeController.head          = avatar.transform.Find("HeadObject").gameObject;
        eyeController.positiveXAxis = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("EyesRight");
        eyeController.positiveYAxis = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("EyesUp");
        eyeController.negativeXAxis = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("EyesLeft");
        eyeController.negativeYAxis = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("EyesDown");

        eyeController.blinkL = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("EyeBlink_L");
        eyeController.blinkR = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("EyeBlink_R");

        // Set camera
        if (cameraObj != null)
        {
            eyeController.target = cameraObj.transform;
            cameraObj.GetComponent <CameraScript>().target = playerObj.transform;
        }

        // send finish command
        AppSocket.SendCommand(AppSocket.SendType.AVATAR_FINISH);
    }
 private void CreateAvatar(string playerId, string avatarCode, string haircutIdentity = null, string hairColor = "#222")
 {
     AppSocket.SendCommand(AppSocket.SendType.AVATAR_LOADING);
     StartCoroutine(Initialize(playerId, avatarCode, haircutIdentity, hairColor));
 }