Skip to content

Commit

Permalink
Refactor validation for avatar applier, remove unused GUI code
Browse files Browse the repository at this point in the history
  • Loading branch information
Krysiek committed Sep 23, 2023
1 parent 458f635 commit 1a0b5ae
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 281 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@

namespace VRF
{
public enum ApplyStatus {
EMPTY,
ADD,
REMOVE,
UPDATE,
BLOCKED
}

interface AvatarApplierInterface
{
void SetAvatar(AvatarDescriptor avatar);
void HandleAdd();
void HandleRemove();
ApplyStatus GetStatus();
}

}
134 changes: 29 additions & 105 deletions Packages/pl.krysiek.cutedancer/Editor/Service/Applier/CuteLayers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,95 +12,28 @@ namespace VRF
{
public class CuteLayers : AvatarApplierInterface
{
enum Status
{
FORM, EMPTY, ADDED, MISSING, DIFFERENCE, UNKNOWN
}

// TODO read from build configuration
static string ACTION_CTRL = Path.Combine("Assets", "CuteDancer", "Build", "CuteDancer-Action.controller");
static string FX_CTRL = Path.Combine("Assets", "CuteDancer", "Build", "CuteDancer-FX.controller");

Status validStat = Status.FORM;
AvatarDescriptor avatar;
AnimatorController actionCtrl;
AnimatorController fxCtrl;

bool actionWD = false;
bool fxWD = false;
public bool ActionWD { get; set; }
public bool FxWD { get; set; }

public void RenderForm()
public CuteLayers()
{
validStat = Validate();

GUIStyle labelStyle = new GUIStyle(EditorStyles.largeLabel);
labelStyle.wordWrap = true;

GUILayout.Label("Select Action and FX controllers used by your avatar.", EditorStyles.largeLabel);
var newActionCtrl = EditorGUILayout.ObjectField("Action", actionCtrl, typeof(AnimatorController), false, GUILayout.ExpandWidth(true)) as AnimatorController;
actionWD = EditorGUILayout.Toggle(new GUIContent("Write Defaults", "VRChat default is OFF, but most avatars has this setting set to ON."), actionWD);
var newFxCtrl = EditorGUILayout.ObjectField("FX", fxCtrl, typeof(AnimatorController), false, GUILayout.ExpandWidth(true)) as AnimatorController;
fxWD = EditorGUILayout.Toggle(new GUIContent("Write Defaults", "VRChat default is OFF, but most avatars has this setting set to ON."), fxWD);

GUILayout.Space(10);

GUILayout.BeginHorizontal();

if (validStat == Status.DIFFERENCE)
{
CuteButtons.RenderButton("Update animator layers", CuteIcons.ADD, HandleUpdate);
}
else
{
CuteButtons.RenderButton("Add animator layers", CuteIcons.ADD, () => HandleAdd(),
!(validStat == Status.EMPTY || validStat == Status.MISSING));
}

CuteButtons.RenderButton("Remove", CuteIcons.REMOVE, () => HandleRemove(),
!(validStat == Status.ADDED || validStat == Status.UNKNOWN), GUILayout.Width(150));

GUILayout.EndHorizontal();
}

public void RenderStatus()
{
switch (validStat)
{
case Status.FORM:
CuteInfoBox.RenderInfoBox(CuteIcons.INFO, "Please select animator controllers.");
break;
case Status.EMPTY:
CuteInfoBox.RenderInfoBox(CuteIcons.WARN, "Layers are not added.");
break;
case Status.MISSING:
CuteInfoBox.RenderInfoBox(CuteIcons.WARN, "Layers are not added (missing controllers will be created).");
break;
case Status.ADDED:
CuteInfoBox.RenderInfoBox(CuteIcons.OK, "Layers are added.");
break;
case Status.DIFFERENCE:
CuteInfoBox.RenderInfoBox(CuteIcons.WARN, "Layers are out of date. Press update button to fix it.");
break;
case Status.UNKNOWN:
CuteInfoBox.RenderInfoBox(CuteIcons.ERROR, "Layers are in mixed state. You can still try to remove any existing layers using Remove button and re-add them.");
break;
}
ActionWD = false;
FxWD = false;
}

public void SetAvatar(AvatarDescriptor avatarDescriptor)
{
avatar = avatarDescriptor;
actionCtrl = Array.Find(avatarDescriptor.baseAnimationLayers, layer => layer.type == AvatarDescriptor.AnimLayerType.Action).animatorController as AnimatorController;
fxCtrl = Array.Find(avatarDescriptor.baseAnimationLayers, layer => layer.type == AvatarDescriptor.AnimLayerType.FX).animatorController as AnimatorController;

if (actionCtrl)
{
actionWD = CuteAnimators.IsAnimatorUsingWD(actionCtrl);
}
if (fxCtrl)
{
fxWD = CuteAnimators.IsAnimatorUsingWD(fxCtrl);
}
actionCtrl = Array.Find(avatarDescriptor.baseAnimationLayers, layer => layer.type == AnimLayerType.Action).animatorController as AnimatorController;
fxCtrl = Array.Find(avatarDescriptor.baseAnimationLayers, layer => layer.type == AnimLayerType.FX).animatorController as AnimatorController;
}

public void ClearForm()
Expand All @@ -117,35 +50,35 @@ public void HandleAdd()

void HandleAdd(bool silent = false)
{
if (!actionCtrl && !CreateController(AvatarDescriptor.AnimLayerType.Action, $"{avatar.name}-Action", silent))
if (!actionCtrl && !CreateController(AnimLayerType.Action, $"{avatar.name}-Action", silent))
{
return;
}

if (!fxCtrl && !CreateController(AvatarDescriptor.AnimLayerType.FX, $"{avatar.name}-FX", silent))
if (!fxCtrl && !CreateController(AnimLayerType.FX, $"{avatar.name}-FX", silent))
{
return;
}

DoBackup();

AnimatorController srcActionCtrl = AssetDatabase.LoadAssetAtPath(ACTION_CTRL, typeof(AnimatorController)) as AnimatorController;
AnimatorController srcFxCtrl = AssetDatabase.LoadAssetAtPath(FX_CTRL, typeof(AnimatorController)) as AnimatorController;
AnimatorController srcActionCtrl = AssetDatabase.LoadAssetAtPath<AnimatorController>(ACTION_CTRL);
AnimatorController srcFxCtrl = AssetDatabase.LoadAssetAtPath<AnimatorController>(FX_CTRL);

Array.ForEach(srcActionCtrl.layers, l => Array.ForEach(l.stateMachine.states, s => s.state.writeDefaultValues = actionWD));
Array.ForEach(srcFxCtrl.layers, l => Array.ForEach(l.stateMachine.states, s => s.state.writeDefaultValues = fxWD));
Array.ForEach(srcActionCtrl.layers, l => Array.ForEach(l.stateMachine.states, s => s.state.writeDefaultValues = ActionWD));
Array.ForEach(srcFxCtrl.layers, l => Array.ForEach(l.stateMachine.states, s => s.state.writeDefaultValues = FxWD));

Debug.Log("Merging controllers [source=" + srcActionCtrl.name + ", desitnation=" + actionCtrl.name + "]");
VRF.VRLabs.AV3Manager.AnimatorCloner.MergeControllers(actionCtrl, srcActionCtrl);
VRLabs.AV3Manager.AnimatorCloner.MergeControllers(actionCtrl, srcActionCtrl);
Debug.Log("Merging controllers [source=" + srcFxCtrl.name + ", desitnation=" + fxCtrl.name + "]");
VRF.VRLabs.AV3Manager.AnimatorCloner.MergeControllers(fxCtrl, srcFxCtrl);

Array.ForEach(srcActionCtrl.layers, l => Array.ForEach(l.stateMachine.states, s => s.state.writeDefaultValues = true));
Array.ForEach(srcFxCtrl.layers, l => Array.ForEach(l.stateMachine.states, s => s.state.writeDefaultValues = true));
VRLabs.AV3Manager.AnimatorCloner.MergeControllers(fxCtrl, srcFxCtrl);
EditorUtility.ClearDirty(srcActionCtrl);
EditorUtility.ClearDirty(srcFxCtrl);

AssetDatabase.SaveAssets();

CuteAnimators.UpdateVrcAnimatorLayerControlAfterClone(actionCtrl, !actionWD);
CuteAnimators.UpdateVrcAnimatorLayerControlAfterClone(actionCtrl, !ActionWD);
}

public void HandleRemove()
Expand All @@ -155,7 +88,7 @@ public void HandleRemove()

void HandleRemove(bool silent = false)
{
if (validStat == Status.UNKNOWN)
if (GetStatus() == ApplyStatus.BLOCKED)
{
if (!EditorUtility.DisplayDialog("CuteScript", "The script will try to remove CuteDance layers from your animators if any exists.\n\nThey are matched by name though, so it may not help.", "Let's try", "Cancel"))
{
Expand Down Expand Up @@ -228,26 +161,18 @@ void DoBackup()
CuteBackup.CreateBackup(AssetDatabase.GetAssetPath(fxCtrl));
}

// TODO temporary validation, true - instaled, false - not
public bool TempValidate()
{
var status = Validate();
return status == Status.ADDED || status == Status.DIFFERENCE || status == Status.UNKNOWN;
}

Status Validate()
public ApplyStatus GetStatus()
{
if (!avatar)
{
return Status.FORM;
return ApplyStatus.EMPTY;
}
if (!actionCtrl || !fxCtrl)
{
return Status.MISSING;
return ApplyStatus.ADD;
}

AnimatorController srcActionCtrl = AssetDatabase.LoadAssetAtPath(ACTION_CTRL, typeof(AnimatorController)) as AnimatorController;
AnimatorController srcFxCtrl = AssetDatabase.LoadAssetAtPath(FX_CTRL, typeof(AnimatorController)) as AnimatorController;
AnimatorController srcActionCtrl = AssetDatabase.LoadAssetAtPath<AnimatorController>(ACTION_CTRL);
AnimatorController srcFxCtrl = AssetDatabase.LoadAssetAtPath<AnimatorController>(FX_CTRL);

bool actionHasLayers = CheckLayersExists(actionCtrl, srcActionCtrl, out bool actionDiffs);
bool fxHasLayers = CheckLayersExists(fxCtrl, srcFxCtrl, out bool fxDiffs);
Expand All @@ -256,16 +181,15 @@ Status Validate()
{
if (actionDiffs || fxDiffs)
{
return Status.DIFFERENCE;
return ApplyStatus.UPDATE;
}
return Status.ADDED;
return ApplyStatus.REMOVE;
}
if (!actionHasLayers && !fxHasLayers)
{
return Status.EMPTY;
return ApplyStatus.ADD;
}
return Status.UNKNOWN;

return ApplyStatus.BLOCKED;
}

bool CheckLayersExists(AnimatorController controller, AnimatorController refCtrl, out bool diffs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,57 +15,9 @@ public class CuteParams : AvatarApplierInterface
// TODO read from build configuration
static string PARAMS_REF = Path.Combine("Assets", "CuteDancer", "Build", "CuteDancer-VRCParams.asset");

enum Status
{
FORM, EMPTY, ADDED, MISSING
}

Status validStat = Status.FORM;
AvatarDescriptor avatar;
ExpressionParameters expressionParams;

public void RenderForm()
{
validStat = Validate();

GUIStyle labelStyle = new GUIStyle(EditorStyles.largeLabel);
labelStyle.wordWrap = true;

GUILayout.Label("Select expression parameters used by your avatar", labelStyle);
expressionParams = EditorGUILayout.ObjectField("Expression Parameters", expressionParams, typeof(ExpressionParameters), false, GUILayout.ExpandWidth(true)) as ExpressionParameters;

GUILayout.Space(10);

GUILayout.BeginHorizontal();

CuteButtons.RenderButton("Add expression parameters", CuteIcons.ADD, HandleAdd,
validStat == Status.ADDED || validStat == Status.FORM);
CuteButtons.RenderButton("Remove", CuteIcons.REMOVE, HandleRemove,
validStat != Status.ADDED,
GUILayout.Width(150));

GUILayout.EndHorizontal();
}

public void RenderStatus()
{
switch (validStat)
{
case Status.FORM:
CuteInfoBox.RenderInfoBox(CuteIcons.INFO, "Please select expression parameters asset.");
break;
case Status.EMPTY:
CuteInfoBox.RenderInfoBox(CuteIcons.WARN, "Expression parameters are not added.");
break;
case Status.ADDED:
CuteInfoBox.RenderInfoBox(CuteIcons.OK, "Expression parameters are added.");
break;
case Status.MISSING:
CuteInfoBox.RenderInfoBox(CuteIcons.WARN, "Expression parameters are not added (missing expression parameters asset will be created).");
break;
}
}

public void SetAvatar(AvatarDescriptor avatarDescriptor)
{
avatar = avatarDescriptor;
Expand Down Expand Up @@ -146,15 +98,15 @@ void DoBackup()
CuteBackup.CreateBackup(AssetDatabase.GetAssetPath(expressionParams));
}

Status Validate()
public ApplyStatus GetStatus()
{
if (!avatar)
{
return Status.FORM;
return ApplyStatus.EMPTY;
}
if (!expressionParams)
{
return Status.MISSING;
return ApplyStatus.ADD;
}
ExpressionParameters paramsRef = AssetDatabase.LoadAssetAtPath(PARAMS_REF, typeof(ExpressionParameters)) as ExpressionParameters;

Expand All @@ -169,9 +121,9 @@ Status Validate()
});
if (notFound)
{
return Status.EMPTY;
return ApplyStatus.ADD;
}
return Status.ADDED;
return ApplyStatus.REMOVE;
}

bool CreateExpressionParams()
Expand Down
Loading

0 comments on commit 1a0b5ae

Please sign in to comment.