private static string BlendShapeNameIfValid(int index, VRCAvatarDescriptor.CustomEyeLookSettings settings) { var count = settings.eyelidsSkinnedMesh.sharedMesh.blendShapeCount; return(index >= 0 && index < count?settings.eyelidsSkinnedMesh.sharedMesh.GetBlendShapeName(index) : null); }
/// <summary> /// 【SDK3】<see cref="BlendShapePreset.Blink"/>を変換し、視線追従を有効化します。 /// </summary> /// <param name="avatar"></param> /// <param name="clips"></param> /// <param name="useShapeKeyNormalsAndTangents"/> private static void EnableEyeLook( GameObject avatar, IEnumerable <VRMBlendShapeClip> clips, bool useShapeKeyNormalsAndTangents ) { VRMBlendShapeClip clip = clips.FirstOrDefault(c => c.Preset == BlendShapePreset.Blink); var lookAtBoneApplyer = avatar.GetComponent <VRMLookAtBoneApplyer>(); if (!clip && !lookAtBoneApplyer) { return; } var renderer = avatar.transform.Find(VRChatUtility.AutoBlinkMeshPath).GetComponent <SkinnedMeshRenderer>(); var mesh = renderer.sharedMesh; if (clip) { mesh.AddBlendShapeFrame( BlendShapeReplacer.BlinkShapeKeyName, 1, BlendShapeReplacer.GenerateShapeKey( clip.ShapeKeyValues, BlendShapeReplacer.GetAllShapeKeys(mesh, useShapeKeyNormalsAndTangents) ), null, null ); EditorUtility.SetDirty(mesh); } #if VRC_SDK_VRCSDK3 var descriptor = avatar.GetComponent <VRCAvatarDescriptor>(); descriptor.enableEyeLook = true; var settings = new VRCAvatarDescriptor.CustomEyeLookSettings(); if (clip) { settings.eyelidType = VRCAvatarDescriptor.EyelidType.Blendshapes; settings.eyelidsSkinnedMesh = renderer; settings.eyelidsBlendshapes = new[] { mesh.blendShapeCount - 1, -1, -1 }; } if (lookAtBoneApplyer) { settings.eyeMovement = new VRCAvatarDescriptor.CustomEyeLookSettings.EyeMovements() { excitement = 0.5f, confidence = 0, }; settings.leftEye = lookAtBoneApplyer.LeftEye.Transform; settings.rightEye = lookAtBoneApplyer.RightEye.Transform; settings.eyesLookingUp = new VRCAvatarDescriptor.CustomEyeLookSettings.EyeRotations() { left = Quaternion.Euler(x: -lookAtBoneApplyer.VerticalUp.CurveYRangeDegree, 0, 0), right = Quaternion.Euler(x: -lookAtBoneApplyer.VerticalUp.CurveYRangeDegree, 0, 0), }; settings.eyesLookingDown = new VRCAvatarDescriptor.CustomEyeLookSettings.EyeRotations() { left = Quaternion.Euler(x: lookAtBoneApplyer.VerticalUp.CurveYRangeDegree, 0, 0), right = Quaternion.Euler(x: lookAtBoneApplyer.VerticalUp.CurveYRangeDegree, 0, 0), }; settings.eyesLookingLeft = new VRCAvatarDescriptor.CustomEyeLookSettings.EyeRotations() { left = Quaternion.Euler(0, y: -lookAtBoneApplyer.HorizontalOuter.CurveYRangeDegree, 0), right = Quaternion.Euler(0, y: -lookAtBoneApplyer.HorizontalInner.CurveYRangeDegree, 0), }; settings.eyesLookingRight = new VRCAvatarDescriptor.CustomEyeLookSettings.EyeRotations() { left = Quaternion.Euler(0, y: lookAtBoneApplyer.HorizontalInner.CurveYRangeDegree, 0), right = Quaternion.Euler(0, y: lookAtBoneApplyer.HorizontalOuter.CurveYRangeDegree, 0), }; } descriptor.customEyeLookSettings = settings; #endif }