public void OnEnable()
    {
        /*
         * if (EyelidSkinnedMesh == null)
         *  EyelidSkinnedMesh = (target as Component).GetComponentInChildren<SkinnedMeshRenderer>(true);
         * if (EyelidBlendShapes == null)
         *  EyelidBlendShapes = GetBlendShapeNames(EyelidSkinnedMesh);
         */

        if (avatarDescriptor == null)
        {
            avatarDescriptor = (VRCAvatarDescriptor)target;
        }

        if (pipelineManager == null)
        {
            pipelineManager = avatarDescriptor.GetComponent <VRC.Core.PipelineManager>();
            if (pipelineManager == null)
            {
                avatarDescriptor.gameObject.AddComponent <VRC.Core.PipelineManager>();
            }
        }

        if (!_doCustomizeAnimLayers.boolValue)
        {
            ResetAnimLayersToDefault();
        }

        EnforceAnimLayerSetup(true);
        serializedObject.ApplyModifiedProperties();

        InitEyeLook();
        Init_Expressions();
    }
        private static void AutoDetectLipSync(VRCAvatarDescriptor avatarDescriptor)
        {
            SkinnedMeshRenderer[] renderers = avatarDescriptor.GetComponentsInChildren <SkinnedMeshRenderer>();

            string[] baseVisemeNames = Enum.GetNames(typeof(VRC_AvatarDescriptor.Viseme));
            int      visemeCount     = baseVisemeNames.Length - 1;

            string[] reversedVisemeNames  = new string[visemeCount];
            string[] reversedVVisemeNames = new string[visemeCount];
            for (int i = 0; i < visemeCount; i++)
            {
                string visemeName = baseVisemeNames[i];
                char[] tmpArray   = visemeName.ToLowerInvariant().ToCharArray();
                Array.Reverse(tmpArray);
                reversedVisemeNames[i]  = new string(tmpArray);
                reversedVVisemeNames[i] = $"{reversedVisemeNames[i]}_v";
            }

            foreach (SkinnedMeshRenderer renderer in renderers)
            {
                if (renderer.sharedMesh.blendShapeCount <= 0)
                {
                    continue;
                }

                if (renderer.sharedMesh.blendShapeCount >= visemeCount)
                {
                    string[] rendererBlendShapeNames = new string[renderer.sharedMesh.blendShapeCount];
                    for (int i = 0; i < renderer.sharedMesh.blendShapeCount; i++)
                    {
                        rendererBlendShapeNames[i] = renderer.sharedMesh.GetBlendShapeName(i);
                    }

                    string[] visemeStrings = new string[visemeCount];
                    int      foundVisemes  = 0;

                    string[] reversedRendererNames         = new string[rendererBlendShapeNames.Length];
                    Dictionary <string, string> reverseMap = new Dictionary <string, string>();

                    for (int i = 0; i < rendererBlendShapeNames.Length; i++)
                    {
                        string rendererBlendShapeName = rendererBlendShapeNames[i];
                        char[] tmpArray = rendererBlendShapeName.ToLowerInvariant().ToCharArray();
                        Array.Reverse(tmpArray);
                        reversedRendererNames[i] = new string(tmpArray);
                        if (reverseMap.ContainsKey(reversedRendererNames[i]))
                        {
                            continue;
                        }
                        reverseMap.Add(reversedRendererNames[i], rendererBlendShapeName);
                    }

                    for (int i = 0; i < reversedVisemeNames.Length; i++)
                    {
                        string visemeName  = reversedVisemeNames[i];
                        string vVisemeName = reversedVVisemeNames[i];

                        List <string> matchingStrings = new List <string>();
                        foreach (string reversedRendererName in reversedRendererNames)
                        {
                            if (reversedRendererName.Contains(vVisemeName))
                            {
                                matchingStrings.Add(reversedRendererName);
                            }
                        }
                        if (matchingStrings.Count == 0)
                        {
                            foreach (string reversedRendererName in reversedRendererNames)
                            {
                                if (reversedRendererName.Contains(visemeName))
                                {
                                    matchingStrings.Add(reversedRendererName);
                                }
                            }
                        }

                        matchingStrings.Sort(new SearchComparer(visemeName));

                        if (matchingStrings.Count <= 0)
                        {
                            continue;
                        }

                        visemeStrings[i] = reverseMap[matchingStrings[0]];
                        foundVisemes++;
                    }

                    //Threshold to see if we did a good enough job to bother showing the user
                    if (foundVisemes > 2)
                    {
                        avatarDescriptor.lipSync           = VRC_AvatarDescriptor.LipSyncStyle.VisemeBlendShape;
                        avatarDescriptor.VisemeSkinnedMesh = renderer;
                        avatarDescriptor.VisemeBlendShapes = visemeStrings;
                        avatarDescriptor.lipSyncJawBone    = null;
                        return;
                    }
                }

                avatarDescriptor.lipSync           = VRC_AvatarDescriptor.LipSyncStyle.JawFlapBlendShape;
                avatarDescriptor.VisemeSkinnedMesh = renderer;
                avatarDescriptor.lipSyncJawBone    = null;
                return;
            }


            if (avatarDescriptor.GetComponent <Animator>().GetBoneTransform(HumanBodyBones.Jaw) == null)
            {
                return;
            }
            avatarDescriptor.lipSync           = VRC_AvatarDescriptor.LipSyncStyle.JawFlapBone;
            avatarDescriptor.lipSyncJawBone    = avatarDescriptor.GetComponent <Animator>().GetBoneTransform(HumanBodyBones.Jaw);
            avatarDescriptor.VisemeSkinnedMesh = null;
        }