@@ -212,17 +212,19 @@ private void WriteRestoreValues(AnimationClip clip)
212212 }
213213
214214 /// <summary>
215- /// 解析 WD 模式:Auto 时参照 VRCFury / Modular Avatar 方案检测已有控制器的 WD 设置
216- /// 规则:
217- /// 1. 跳过 isDefault 的 Playable Layer(未自定义,无分配控制器)
218- /// 2. 跳过 animatorController 为 null 的层(参考 Av3 Manager)
219- /// 3. 跳过 VRChat 内置控制器(名称以 vrc_ 开头)
220- /// 4. 跳过 ASS 自己生成的层(ASS_ 前缀)
221- /// 5. 跳过 Additive 层(必须始终 WD On)
222- /// 6. 跳过 Direct BlendTree 单状态层(必须始终 WD On,参考 Modular Avatar IsWriteDefaultsRequiredLayer)
223- /// 7. 跳过没有 Motion 的空状态(不含有效动画,WD 设置无意义)
224- /// 8. 只要存在任何 WD Off 状态就使用 WD Off
225- /// 9. 全部为 WD On(或无有效状态)才使用 WD On
215+ /// 解析 WD 模式:Auto 时优先复用 VRCFury FixWriteDefaults 的用户设置,否则自动扫描
216+ /// Auto 流程:
217+ /// 1. 检查 VRCFury FixWriteDefaults:ForceOn/ForceOff → 直接复用;Auto/Disabled → 回退扫描
218+ /// 扫描规则:
219+ /// 2. 跳过 isDefault 的 Playable Layer(未自定义,无分配控制器)
220+ /// 3. 跳过 animatorController 为 null 的层(参考 Av3 Manager)
221+ /// 4. 跳过 VRChat 内置控制器(名称以 vrc_ 开头)
222+ /// 5. 跳过 ASS 自己生成的层(ASS_ 前缀)
223+ /// 6. 跳过 Additive 层(必须始终 WD On)
224+ /// 7. 跳过 Direct BlendTree 单状态层(必须始终 WD On,参考 Modular Avatar IsWriteDefaultsRequiredLayer)
225+ /// 8. 跳过没有 Motion 的空状态(不含有效动画,WD 设置无意义)
226+ /// 9. 只要存在任何 WD Off 状态就使用 WD Off
227+ /// 10. 全部为 WD On(或无有效状态)才使用 WD On
226228 /// </summary>
227229 private bool ResolveWriteDefaults ( )
228230 {
@@ -231,6 +233,11 @@ private bool ResolveWriteDefaults()
231233 if ( config . writeDefaultsMode == ASSComponent . WriteDefaultsMode . Off )
232234 return false ;
233235
236+ // Auto 模式:先检查 VRCFury 是否已指定 WD 模式
237+ var externalWd = TryResolveFromExternalTools ( ) ;
238+ if ( externalWd . HasValue )
239+ return externalWd . Value ;
240+
234241 // 收集所有 Playable Layer 的 AnimatorController(去重)
235242 var controllers = new HashSet < AnimatorController > ( ) ;
236243 if ( descriptor != null )
@@ -272,6 +279,43 @@ private bool ResolveWriteDefaults()
272279 return useWdOn ;
273280 }
274281
282+ /// <summary>
283+ /// 通过反射检查 VRCFury FixWriteDefaults 组件的 WD 设置
284+ /// - ForceOn/ForceOff → 直接复用
285+ /// - Auto → VRCFury 已在构建流程中统一 controller WD,回退到扫描确认
286+ /// - Disabled / 未检测到 → 回退到 ASS 自动扫描
287+ /// </summary>
288+ private bool ? TryResolveFromExternalTools ( )
289+ {
290+ foreach ( var mb in avatarRoot . GetComponentsInChildren < MonoBehaviour > ( true ) )
291+ {
292+ if ( mb == null ) continue ;
293+ if ( mb . GetType ( ) . FullName != "VF.Model.VRCFury" ) continue ;
294+
295+ var content = mb . GetType ( ) . GetField ( "content" ) ? . GetValue ( mb ) ;
296+ if ( content == null || content . GetType ( ) . Name != "FixWriteDefaults" ) continue ;
297+
298+ var modeName = content . GetType ( ) . GetField ( "mode" ) ? . GetValue ( content ) ? . ToString ( ) ;
299+ switch ( modeName )
300+ {
301+ case "ForceOn" :
302+ Debug . Log ( "[ASS] WD Auto → On (VRCFury FixWriteDefaults = ForceOn)" ) ;
303+ return true ;
304+ case "ForceOff" :
305+ Debug . Log ( "[ASS] WD Auto → Off (VRCFury FixWriteDefaults = ForceOff)" ) ;
306+ return false ;
307+ case "Auto" :
308+ Debug . Log ( "[ASS] 检测到 VRCFury FixWriteDefaults = Auto,VRCFury 已统一 controller WD,扫描确认" ) ;
309+ return null ;
310+ case "Disabled" :
311+ Debug . Log ( "[ASS] VRCFury FixWriteDefaults = Disabled,回退到 ASS 自动检测" ) ;
312+ return null ;
313+ }
314+ }
315+
316+ return null ;
317+ }
318+
275319 /// <summary>
276320 /// 判断一个层是否必须始终 WD On(参考 Modular Avatar IsWriteDefaultsRequiredLayer)
277321 /// 条件:Additive 层,或单状态无转换且 Motion 为 Direct BlendTree 的层
0 commit comments