Created
April 11, 2026 11:35
-
-
Save malaybaku/7323085e13e571e8d48bbc57468acd4a to your computer and use it in GitHub Desktop.
Example: setup block flag for VRM0.x models with Vrm10.Load method
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Threading; | |
| using System.Threading.Tasks; | |
| using UniGLTF; | |
| using UniGLTF.Extensions.VRMC_vrm; | |
| using UniVRM10; | |
| public static class Vrm10ExternalExpressionMigrationSample | |
| { | |
| public static async Task<Vrm10Instance> LoadVrm10BytesAsync( | |
| byte[] bytes, | |
| bool showMeshes = true, | |
| IAwaitCaller awaitCaller = null, | |
| ITextureDeserializer textureDeserializer = null, | |
| IMaterialDescriptorGenerator materialGenerator = null, | |
| CancellationToken ct = default, | |
| ImporterContextSettings importerContextSettings = null, | |
| IVrm10SpringBoneRuntime springboneRuntime = null) | |
| { | |
| var wasVrm0X = false; | |
| var instance = await Vrm10.LoadBytesAsync( | |
| bytes, | |
| canLoadVrm0X: true, | |
| showMeshes: showMeshes, | |
| awaitCaller: awaitCaller, | |
| textureDeserializer: textureDeserializer, | |
| materialGenerator: materialGenerator, | |
| vrmMetaInformationCallback: (_, _, vrm0Meta) => | |
| { | |
| wasVrm0X = vrm0Meta != null; | |
| }, | |
| ct: ct, | |
| importerContextSettings: importerContextSettings, | |
| springboneRuntime: springboneRuntime); | |
| if (wasVrm0X) | |
| { | |
| ApplyVrm0XExpressionMigration(instance); | |
| } | |
| return instance; | |
| } | |
| // VRM0.xのモデルについて、大体の表情をリップシンク/まばたきと共存しない扱いにすることで、表情の多重適用を防ぐ | |
| private static void ApplyVrm0XExpressionMigration(Vrm10Instance instance) | |
| { | |
| if (instance == null || instance.Vrm == null) | |
| { | |
| return; | |
| } | |
| foreach (var (preset, clip) in instance.Vrm.Expression.Clips) | |
| { | |
| if (clip == null || !ShouldBlockOverride(preset)) | |
| { | |
| continue; | |
| } | |
| clip.OverrideBlink = ExpressionOverrideType.block; | |
| clip.OverrideLookAt = ExpressionOverrideType.block; | |
| clip.OverrideMouth = ExpressionOverrideType.block; | |
| } | |
| } | |
| private static bool ShouldBlockOverride(ExpressionPreset preset) | |
| { | |
| switch (preset) | |
| { | |
| case ExpressionPreset.aa: | |
| case ExpressionPreset.ih: | |
| case ExpressionPreset.ou: | |
| case ExpressionPreset.ee: | |
| case ExpressionPreset.oh: | |
| case ExpressionPreset.blink: | |
| case ExpressionPreset.blinkLeft: | |
| case ExpressionPreset.blinkRight: | |
| case ExpressionPreset.neutral: // この行はアプリによってはコメントアウトし、neutralとblink/lipSyncは共存させてもOK | |
| return false; | |
| default: | |
| return true; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment