80 lines
3.8 KiB
C#
80 lines
3.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEditor.Animations;
|
|
using UnityEngine;
|
|
using VF.Builder;
|
|
using VF.Feature.Base;
|
|
using VRC.SDK3.Avatars.Components;
|
|
using VRC.SDKBase;
|
|
|
|
namespace VF.Feature {
|
|
/**
|
|
* This builder is responsible for correcting any AnimatorLayerControl behaviours in
|
|
* the animators which may have been broken by VRCFury adding / deleting layers
|
|
* while doing other things.
|
|
*/
|
|
public class AnimatorLayerControlOffsetBuilder : FeatureBuilder {
|
|
private Dictionary<VRCAnimatorLayerControl, AnimatorStateMachine> mapping
|
|
= new Dictionary<VRCAnimatorLayerControl, AnimatorStateMachine>();
|
|
|
|
[FeatureBuilderAction(FeatureOrder.AnimatorLayerControlRecordBase)]
|
|
public void RecordBase() {
|
|
RegisterControllerSet(manager.GetAllUsedControllers().Select(c => (c.GetType(), c.GetRaw())));
|
|
}
|
|
|
|
[FeatureBuilderAction(FeatureOrder.AnimatorLayerControlFix)]
|
|
public void Fix() {
|
|
var smToTypeAndNumber = new Dictionary<AnimatorStateMachine, (VRCAvatarDescriptor.AnimLayerType, int)>();
|
|
foreach (var c in manager.GetAllUsedControllers()) {
|
|
foreach (var (i,l) in c.GetLayers().Select((l,i) => (i,l))) {
|
|
smToTypeAndNumber[l] = (c.GetType(), i);
|
|
}
|
|
}
|
|
|
|
foreach (var c in manager.GetAllUsedControllers()) {
|
|
foreach (var l in c.GetLayers()) {
|
|
AnimatorIterator.ForEachBehaviour(l, (b, add) => {
|
|
if (!(b is VRCAnimatorLayerControl control)) return true;
|
|
if (!mapping.TryGetValue(control, out var targetSm)) {
|
|
Debug.LogError("Removing invalid AnimatorLayerControl (not found in mapping??) " + b);
|
|
return false;
|
|
}
|
|
if (!smToTypeAndNumber.TryGetValue(targetSm, out var pair)) {
|
|
Debug.LogError("Removing invalid AnimatorLayerControl (target sm has disappeared) " + b);
|
|
return false;
|
|
}
|
|
var (newType, newI) = pair;
|
|
var newCastedType = VRCFEnumUtils.Parse<VRC_AnimatorLayerControl.BlendableLayer>(
|
|
VRCFEnumUtils.GetName(newType));
|
|
Debug.LogWarning($"Rewriting {b} from {control.playable}:{control.layer} to {newCastedType}:{newI}");
|
|
control.playable = newCastedType;
|
|
control.layer = newI;
|
|
return true;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
public void RegisterControllerSet(IEnumerable<(VRCAvatarDescriptor.AnimLayerType, AnimatorController)> set) {
|
|
foreach (var (type, controller) in set) {
|
|
foreach (var layer in controller.layers) {
|
|
AnimatorIterator.ForEachBehaviour(layer.stateMachine, (b, add) => {
|
|
if (b is VRCAnimatorLayerControl control) {
|
|
var targetController = set
|
|
.Where(tuple =>
|
|
VRCFEnumUtils.GetName(tuple.Item1) == VRCFEnumUtils.GetName(control.playable))
|
|
.Select(tuple => tuple.Item2)
|
|
.FirstOrDefault();
|
|
if (targetController == null) return false;
|
|
if (control.layer < 0 || control.layer >= targetController.layers.Length) return false;
|
|
var targetSm = targetController.layers[control.layer].stateMachine;
|
|
mapping[control] = targetSm;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |