Skip to content

Commit c6f1587

Browse files
committed
feat: WD Auto VRCF
1 parent 5d33be0 commit c6f1587

5 files changed

Lines changed: 108 additions & 23 deletions

File tree

Assets/UnityBox.unity

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17444,6 +17444,7 @@ GameObject:
1744417444
- component: {fileID: 1679610428}
1744517445
- component: {fileID: 1679610433}
1744617446
- component: {fileID: 1679610432}
17447+
- component: {fileID: 1679610434}
1744717448
m_Layer: 0
1744817449
m_Name: TEST ASS
1744917450
m_TagString: Untagged
@@ -18382,6 +18383,34 @@ MonoBehaviour:
1838218383
skipCompleteGraphToEntryExit: 0
1838318384
skipReplaceEndBoneWithEndpointPosition: 0
1838418385
skipOptimizationWarnings: 0
18386+
--- !u!114 &1679610434
18387+
MonoBehaviour:
18388+
m_ObjectHideFlags: 0
18389+
m_CorrespondingSourceObject: {fileID: 0}
18390+
m_PrefabInstance: {fileID: 0}
18391+
m_PrefabAsset: {fileID: 0}
18392+
m_GameObject: {fileID: 1679610426}
18393+
m_Enabled: 1
18394+
m_EditorHideFlags: 0
18395+
m_Script: {fileID: 11500000, guid: d9e94e501a2d4c95bff3d5601013d923, type: 3}
18396+
m_Name:
18397+
m_EditorClassIdentifier:
18398+
version: 3
18399+
unityVersion: 2022.3.22f1
18400+
vrcfuryVersion: 1.1279.0
18401+
somethingIsBroken: 0
18402+
config:
18403+
features: []
18404+
content:
18405+
rid: 5603525159769079813
18406+
references:
18407+
version: 2
18408+
RefIds:
18409+
- rid: 5603525159769079813
18410+
type: {class: FixWriteDefaults, ns: VF.Model.Feature, asm: VRCFury}
18411+
data:
18412+
version: 0
18413+
mode: 0
1838518414
--- !u!1 &1689731932
1838618415
GameObject:
1838718416
m_ObjectHideFlags: 0

Assets/UnityBox/AvatarSecuritySystem/Editor/ASS_TechnicalDoc.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,21 @@ Avatar 加载
267267

268268
#### 4.1.5 Write Defaults 自动检测 (ResolveWriteDefaults)
269269

270-
Auto 模式下扫描所有 Playable Layer 的 AnimatorController
270+
Auto 模式下的检测流程分为两个阶段
271271

272-
**跳过规则**:
272+
**阶段 1 — VRCFury 检查** (`TryResolveFromExternalTools`):
273+
274+
通过反射检查 Avatar 上的 VRCFury `FixWriteDefaults` 组件(internal 类型,需反射访问):
275+
276+
- 遍历 `VF.Model.VRCFury` 组件的 `content` 字段
277+
- `ForceOn` → 直接返回 WD On
278+
- `ForceOff` → 直接返回 WD Off
279+
- `Auto` → VRCFury 已在 `-10000` 阶段统一 controller WD,记录日志后进入阶段 2
280+
- `Disabled` → VRCFury 不修复非自己管理的层,进入阶段 2
281+
282+
**阶段 2 — Controller 扫描**(回退方案):
283+
284+
扫描所有 Playable Layer 的 AnimatorController,跳过规则:
273285

274286
1. `isDefault` 的 Playable Layer(未自定义)
275287
2. `animatorController` 为 null 的层
@@ -607,10 +619,10 @@ Inactive ──(IsLocal && TimeUp)──→ Active
607619

608620
#### 锁定选项
609621

610-
| 参数 | 类型 | 默认值 | 说明 |
611-
| --------------------- | ----------------- | ------ | ---------------------------------------------------------- |
612-
| `disableRootChildren` | bool | true | 锁定时禁用 Avatar 根子对象 |
613-
| `writeDefaultsMode` | WriteDefaultsMode | Auto | Auto = 自动检测 / On = 依赖自动恢复 / Off = 显式写入恢复值 |
622+
| 参数 | 类型 | 默认值 | 说明 |
623+
| --------------------- | ----------------- | ------ | ----------------------------------------------------------------------------------- |
624+
| `disableRootChildren` | bool | true | 锁定时禁用 Avatar 根子对象 |
625+
| `writeDefaultsMode` | WriteDefaultsMode | Auto | Auto = 自动检测(优先复用 VRCFury 设置) / On = 依赖自动恢复 / Off = 显式写入恢复值 |
614626

615627
#### 高级选项
616628

@@ -794,7 +806,7 @@ int particleBudget = Mathf.Max(0, Constants.PARTICLE_MAX_COUNT - existingParticl
794806

795807
### 10.2 Write Defaults 模式
796808

797-
- **Auto(推荐)**自动检测已有 Controller 的 WD 设置,遵循大多数状态的设置
809+
- **Auto(推荐)**优先复用 VRCFury `FixWriteDefaults` (ForceOn/ForceOff) 的用户设置;若为 Auto/Disabled 或不存在,则扫描 Controller 确认
798810
- **WD On**:动画结束后参数自动恢复默认值,更简洁
799811
- **WD Off**:每个状态需要显式写入所有受控属性的恢复值
800812
- 系统自动根据配置选择对应的动画生成策略

Assets/UnityBox/AvatarSecuritySystem/Editor/Lock.cs

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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 的层

Assets/UnityBox/AvatarSecuritySystem/Editor/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -449,10 +449,10 @@ ASS_Defense Layer
449449
450450
#### 锁定选项
451451
452-
| 属性 | 类型 | 默认值 | 说明 |
453-
| --------------------- | ------------------- | ------ | ---------------------------- |
454-
| `disableRootChildren` | `bool` | `true` | 锁定时隐藏 Avatar 根级子对象 |
455-
| `writeDefaultsMode` | `WriteDefaultsMode` | `Auto` | Auto=自动检测 / On / Off |
452+
| 属性 | 类型 | 默认值 | 说明 |
453+
| --------------------- | ------------------- | ------ | ------------------------------------------------- |
454+
| `disableRootChildren` | `bool` | `true` | 锁定时隐藏 Avatar 根级子对象 |
455+
| `writeDefaultsMode` | `WriteDefaultsMode` | `Auto` | Auto=自动检测(优先复用 VRCFury 设置) / On / Off |
456456
457457
#### 高级选项
458458

Assets/UnityBox/AvatarSecuritySystem/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "top.sealoong.unitybox.avatar-security-system",
33
"displayName": "Avatar Security System",
4-
"version": "0.3.1",
4+
"version": "0.3.2",
55
"description": "A VRChat avatar editor tool for protecting avatars with gesture-based password security system.",
66
"unity": "2022.3",
77
"author": {

0 commit comments

Comments
 (0)