diff --git a/CHANGELOG-PRERELEASE.md b/CHANGELOG-PRERELEASE.md index 245b909d..d2d6c784 100644 --- a/CHANGELOG-PRERELEASE.md +++ b/CHANGELOG-PRERELEASE.md @@ -16,6 +16,8 @@ The format is based on [Keep a Changelog]. ### Removed ### Fixed +- Animation bindings for BoxCollider generated by VRCStation will be removed `#1331` + - This might break the GogoLoco or other flying avatar that supports Quest / Android. ### Security diff --git a/CHANGELOG.md b/CHANGELOG.md index 5faf85c8..db9f5efe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -131,6 +131,8 @@ The format is based on [Keep a Changelog]. - Fix non-VRChat project support `#1310` - 'shader' doesn't have a float or range property 'prop' error `#1312` - Error if all components are on inactive GameObject `#1318` +- Animation bindings for BoxCollider generated by VRCStation will be removed `#1331` + - This might break the GogoLoco or other flying avatar that supports Quest / Android. ### Security diff --git a/Editor/ObjectMapping/AnimationObjectMapper.cs b/Editor/ObjectMapping/AnimationObjectMapper.cs index 763b0ca3..ba501703 100644 --- a/Editor/ObjectMapping/AnimationObjectMapper.cs +++ b/Editor/ObjectMapping/AnimationObjectMapper.cs @@ -186,7 +186,26 @@ public MappedGameObjectInfo(ObjectMapping objectMapping, string? newPath, Before var component = EditorUtility.InstanceIDToObject(instanceId); if (!component) + { +#if AAO_VRCSDK3_AVATARS + // See https://github.com/anatawa12/AvatarOptimizer/issues/1330 + // Some flying avatar gimmicks use VRCStation to make the Collider for flying. + // (Box Collider is not whitelisted for quest avatars) + // Therefore, we need to keep animation bindings for BoxCollider (and Collider) if + // the GameObject has VRCStation component. + if (type == typeof(BoxCollider) || type == typeof(Collider)) + { + var (stationInstanceId, _) = gameObjectInfo.GetComponentByType(typeof(VRC.SDK3.Avatars.Components.VRCStation)); + if (EditorUtility.InstanceIDToObject(stationInstanceId) != null) + { + goto componentLive; + } + } +#endif + return Array.Empty<(string path, Type type, string propertyName)>(); // this means removed + } + componentLive:; if (gameObjectInfo.NewPath == null) return Array.Empty<(string path, Type type, string propertyName)>(); if (path == gameObjectInfo.NewPath) return null;