Skip to content
This repository was archived by the owner on May 25, 2023. It is now read-only.

Commit 3e536c5

Browse files
authored
Merge pull request #20 from killfrenzy96/master
Various fixes and improvements
2 parents 07333ee + e862f1d commit 3e536c5

File tree

1 file changed

+206
-44
lines changed

1 file changed

+206
-44
lines changed

Editor/VRC3CVR.cs

+206-44
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,17 @@ void OnGUI()
5252
CustomGUI.LineGap();
5353

5454
CustomGUI.HorizontalRule();
55-
55+
5656
CustomGUI.LineGap();
5757

5858
CustomGUI.BoldLabel("Step 1: Select your avatar");
5959

6060
CustomGUI.SmallLineGap();
6161

6262
vrcAvatarDescriptor = (VRCAvatarDescriptor)EditorGUILayout.ObjectField("Avatar", vrcAvatarDescriptor, typeof(VRCAvatarDescriptor));
63-
63+
6464
CustomGUI.SmallLineGap();
65-
65+
6666
CustomGUI.BoldLabel("Step 2: Configure settings");
6767

6868
CustomGUI.SmallLineGap();
@@ -84,9 +84,9 @@ void OnGUI()
8484
CustomGUI.ItalicLabel("Always deletes contact receivers and senders");
8585

8686
CustomGUI.SmallLineGap();
87-
87+
8888
CustomGUI.BoldLabel("Step 3: Convert");
89-
89+
9090
CustomGUI.SmallLineGap();
9191

9292
EditorGUI.BeginDisabledGroup(GetIsReadyForConvert() == false);
@@ -141,7 +141,7 @@ void CreateChilloutAvatar() {
141141
chilloutAvatarGameObject = vrcAvatarDescriptor.gameObject;
142142
}
143143
}
144-
144+
145145
void HideOriginalAvatar() {
146146
vrcAvatarDescriptor.gameObject.SetActive(false);
147147
}
@@ -221,7 +221,7 @@ void BuildChilloutAnimatorWithParams()
221221
void DeleteVrcComponents()
222222
{
223223
Debug.Log("Deleting VRC components...");
224-
224+
225225
DestroyImmediate(chilloutAvatarGameObject.GetComponent(typeof(VRC.Core.PipelineManager)));
226226

227227
var vrcComponents = chilloutAvatarGameObject.GetComponentsInChildren(typeof(Component), true).ToList().Where(c => c.GetType().Name.StartsWith("VRC")).ToList();
@@ -231,11 +231,11 @@ void DeleteVrcComponents()
231231

232232
foreach (var component in vrcComponents) {
233233
string componentName = component.GetType().Name;
234-
234+
235235
if (!shouldDeletePhysBones && componentName.Contains("PhysBone")) {
236236
continue;
237237
}
238-
238+
239239
Debug.Log(component.name + "." + componentName);
240240

241241
DestroyImmediate(component);
@@ -468,62 +468,218 @@ AnimatorControllerParameter[] GetParametersWithoutDupes(AnimatorControllerParame
468468
return finalParams.ToArray();
469469
}
470470

471+
AnimatorTransition[] ProcessTransitions(AnimatorTransition[] transitions)
472+
{
473+
return ProcessTransitions<AnimatorTransition>(transitions);
474+
}
475+
471476
AnimatorStateTransition[] ProcessTransitions(AnimatorStateTransition[] transitions)
472477
{
473-
List<AnimatorStateTransition> transitionsToAdd = new List<AnimatorStateTransition>();
478+
return ProcessTransitions<AnimatorStateTransition>(transitions);
479+
}
480+
481+
AnimatorTranstitionType[] ProcessTransitions<AnimatorTranstitionType>(AnimatorTranstitionType[] transitions) where AnimatorTranstitionType : AnimatorTransitionBase, new()
482+
{
483+
List<AnimatorTranstitionType> transitionsToAdd = new List<AnimatorTranstitionType>();
474484

475485
for (int t = 0; t < transitions.Length; t++)
476486
{
477487
List<AnimatorCondition> conditionsToAdd = new List<AnimatorCondition>();
488+
AnimatorTranstitionType transition = transitions[t];
478489

479490
// Debug.Log(transitions[t].conditions.Length + " conditions");
480491

481-
for (int c = 0; c < transitions[t].conditions.Length; c++)
492+
ProcessTransition(transition, transitionsToAdd, conditionsToAdd);
493+
}
494+
495+
AnimatorTranstitionType[] newTransitions = new AnimatorTranstitionType[transitions.Length + transitionsToAdd.Count];
496+
497+
transitions.CopyTo(newTransitions, 0);
498+
transitionsToAdd.ToArray().CopyTo(newTransitions, transitions.Length);
499+
500+
return newTransitions;
501+
}
502+
503+
void ProcessTransition<AnimatorTranstitionType>(AnimatorTranstitionType transition, List<AnimatorTranstitionType> transitionsToAdd, List<AnimatorCondition> conditionsToAdd, bool isDuplicate = false) where AnimatorTranstitionType : AnimatorTransitionBase, new()
504+
{
505+
// Convert GestureLeft/GestureRight to ChilloutVR
506+
for (int c = 0; c < transition.conditions.Length; c++)
507+
{
508+
AnimatorCondition condition = transition.conditions[c];
509+
510+
if (condition.parameter == "GestureLeft" || condition.parameter == "GestureRight")
482511
{
483-
AnimatorCondition condition = transitions[t].conditions[c];
512+
float chilloutGestureNumber = GetChilloutGestureNumberForVrchatGestureNumber(condition.threshold);
484513

485-
if (condition.parameter == "GestureLeft" || condition.parameter == "GestureRight")
514+
if (condition.mode == AnimatorConditionMode.Equals)
486515
{
487-
float chilloutGestureNumber = GetChilloutGestureNumberForVrchatGestureNumber(condition.threshold);
516+
float thresholdLow = (float)(chilloutGestureNumber - 0.1);
517+
float thresholdHigh = (float)(chilloutGestureNumber + 0.1);
488518

489-
if (condition.mode == AnimatorConditionMode.Equals)
519+
// Look for GestureWeight and adjust threshold
520+
if (chilloutGestureNumber == 1f) // Fist only
490521
{
491-
AnimatorCondition newConditionLessThan = new AnimatorCondition();
492-
newConditionLessThan.parameter = condition.parameter;
493-
newConditionLessThan.mode = AnimatorConditionMode.Less;
494-
newConditionLessThan.threshold = (float)(chilloutGestureNumber + 0.1);
522+
thresholdLow = 0.01f;
523+
524+
for (int w = 0; w < transition.conditions.Length; w++)
525+
{
526+
AnimatorCondition conditionW = transition.conditions[w];
527+
if (
528+
(condition.parameter == "GestureLeft" && conditionW.parameter == "GestureLeftWeight") ||
529+
(condition.parameter == "GestureRight" && conditionW.parameter == "GestureRightWeight")
530+
) {
531+
if (conditionW.mode == AnimatorConditionMode.Less)
532+
{
533+
thresholdHigh = conditionW.threshold;
534+
}
535+
else
536+
{
537+
thresholdLow = conditionW.threshold;
538+
}
539+
}
540+
}
541+
}
495542

496-
conditionsToAdd.Add(newConditionLessThan);
543+
// Create replace conditions for ChilloutVR
544+
AnimatorCondition newConditionLessThan = new AnimatorCondition();
545+
newConditionLessThan.parameter = condition.parameter;
546+
newConditionLessThan.mode = AnimatorConditionMode.Less;
547+
newConditionLessThan.threshold = thresholdHigh;
548+
549+
conditionsToAdd.Add(newConditionLessThan);
550+
551+
AnimatorCondition newConditionGreaterThan = new AnimatorCondition();
552+
newConditionGreaterThan.parameter = condition.parameter;
553+
newConditionGreaterThan.mode = AnimatorConditionMode.Greater;
554+
newConditionGreaterThan.threshold = thresholdLow;
555+
556+
conditionsToAdd.Add(newConditionGreaterThan);
557+
}
558+
else if (condition.mode == AnimatorConditionMode.NotEqual)
559+
{
560+
float thresholdLow = (float)(chilloutGestureNumber - 0.1);
561+
float thresholdHigh = (float)(chilloutGestureNumber + 0.1);
562+
563+
if (chilloutGestureNumber == 1f) // Fist only
564+
{
565+
thresholdLow = 0.01f;
566+
}
497567

568+
if (isDuplicate) {
569+
// Add greater than transition to duplicate
498570
AnimatorCondition newConditionGreaterThan = new AnimatorCondition();
499571
newConditionGreaterThan.parameter = condition.parameter;
500572
newConditionGreaterThan.mode = AnimatorConditionMode.Greater;
501-
newConditionGreaterThan.threshold = (float)(chilloutGestureNumber - 0.1);
573+
newConditionGreaterThan.threshold = thresholdHigh;
502574

503575
conditionsToAdd.Add(newConditionGreaterThan);
504-
} else if (condition.mode == AnimatorConditionMode.NotEqual)
505-
{
576+
577+
} else {
578+
// Change transition to use less than
506579
AnimatorCondition newConditionLessThan = new AnimatorCondition();
507580
newConditionLessThan.parameter = condition.parameter;
508581
newConditionLessThan.mode = AnimatorConditionMode.Less;
509-
newConditionLessThan.threshold = (float)(chilloutGestureNumber - 0.1);
582+
newConditionLessThan.threshold = thresholdLow;
510583

511584
conditionsToAdd.Add(newConditionLessThan);
585+
586+
// Duplicate transition to create the "or greater than" transition
587+
AnimatorTranstitionType newTransition = new AnimatorTranstitionType();
588+
if (newTransition is AnimatorStateTransition) {
589+
AnimatorStateTransition newTransitionTyped = newTransition as AnimatorStateTransition;
590+
AnimatorStateTransition transitionTyped = transition as AnimatorStateTransition;
591+
newTransitionTyped.duration = transitionTyped.duration;
592+
newTransitionTyped.canTransitionToSelf = transitionTyped.canTransitionToSelf;
593+
newTransitionTyped.exitTime = transitionTyped.exitTime;
594+
newTransitionTyped.hasExitTime = transitionTyped.hasExitTime;
595+
newTransitionTyped.hasFixedDuration = transitionTyped.hasFixedDuration;
596+
newTransitionTyped.interruptionSource = transitionTyped.interruptionSource;
597+
newTransitionTyped.offset = transitionTyped.offset;
598+
newTransitionTyped.orderedInterruption = transitionTyped.orderedInterruption;
599+
}
600+
601+
newTransition.name = transition.name;
602+
newTransition.destinationState = transition.destinationState;
603+
newTransition.destinationStateMachine = transition.destinationStateMachine;
604+
newTransition.hideFlags = transition.hideFlags;
605+
newTransition.isExit = transition.isExit;
606+
newTransition.solo = transition.solo;
607+
newTransition.mute = transition.mute;
608+
609+
for (int c2 = 0; c2 < transition.conditions.Length; c2++)
610+
{
611+
newTransition.AddCondition(transition.conditions[c2].mode, transition.conditions[c2].threshold, transition.conditions[c2].parameter);
612+
}
613+
614+
List<AnimatorTranstitionType> transitionsToAdd2 = new List<AnimatorTranstitionType>();
615+
List<AnimatorCondition> conditionsToAdd2 = new List<AnimatorCondition>();
616+
617+
ProcessTransition(newTransition, transitionsToAdd2, conditionsToAdd2, true);
618+
newTransition.conditions = conditionsToAdd2.ToArray();
619+
620+
transitionsToAdd.Add(newTransition);
512621
}
513-
} else {
514-
conditionsToAdd.Add(condition);
515622
}
516623
}
624+
else if (condition.parameter == "GestureLeftWeight" || condition.parameter == "GestureRightWeight")
625+
{
626+
// Look for fist gesture and create condition if needed
627+
bool gestureFound = false;
517628

518-
transitions[t].conditions = conditionsToAdd.ToArray();
519-
}
629+
for (int w = 0; w < transition.conditions.Length; w++)
630+
{
631+
AnimatorCondition conditionW = transition.conditions[w];
632+
if (
633+
(condition.parameter == "GestureLeftWeight" && conditionW.parameter == "GestureLeft") ||
634+
(condition.parameter == "GestureRightWeight" && conditionW.parameter == "GestureRight")
635+
) {
636+
if (conditionW.threshold == 1f) {
637+
gestureFound = true;
638+
break;
639+
}
640+
}
641+
}
520642

521-
AnimatorStateTransition[] newTransitions = new AnimatorStateTransition[transitions.Length + transitionsToAdd.Count];
643+
// Create condition if gesture weight is used by itself
644+
if (!gestureFound)
645+
{
646+
float thresholdLow = -0.1f;
647+
float thresholdHigh = 1.1f;
522648

523-
transitions.CopyTo(newTransitions, 0);
524-
transitionsToAdd.ToArray().CopyTo(newTransitions, transitions.Length);
649+
if (condition.mode == AnimatorConditionMode.Less)
650+
{
651+
thresholdHigh = condition.threshold;
652+
}
653+
else
654+
{
655+
thresholdLow = condition.threshold;
656+
}
525657

526-
return newTransitions;
658+
string parameterName = condition.parameter == "GestureLeftWeight" ? "GestureLeft" : "GestureRight";
659+
660+
// Create replace conditions for ChilloutVR
661+
AnimatorCondition newConditionLessThan = new AnimatorCondition();
662+
newConditionLessThan.parameter = parameterName;
663+
newConditionLessThan.mode = AnimatorConditionMode.Less;
664+
newConditionLessThan.threshold = thresholdHigh;
665+
666+
conditionsToAdd.Add(newConditionLessThan);
667+
668+
AnimatorCondition newConditionGreaterThan = new AnimatorCondition();
669+
newConditionGreaterThan.parameter = parameterName;
670+
newConditionGreaterThan.mode = AnimatorConditionMode.Greater;
671+
newConditionGreaterThan.threshold = thresholdLow;
672+
673+
conditionsToAdd.Add(newConditionGreaterThan);
674+
}
675+
}
676+
else
677+
{
678+
conditionsToAdd.Add(condition);
679+
}
680+
}
681+
682+
transition.conditions = conditionsToAdd.ToArray();
527683
}
528684

529685
void ProcessStateMachine(AnimatorStateMachine stateMachine)
@@ -555,7 +711,8 @@ void ProcessStateMachine(AnimatorStateMachine stateMachine)
555711
state.transitions = newTransitions;
556712
}
557713

558-
ProcessTransitions(stateMachine.anyStateTransitions);
714+
stateMachine.anyStateTransitions = ProcessTransitions(stateMachine.anyStateTransitions);
715+
stateMachine.entryTransitions = ProcessTransitions(stateMachine.entryTransitions);
559716

560717
if (stateMachine.stateMachines.Length > 0)
561718
{
@@ -639,22 +796,27 @@ void MergeVrcAnimatorIntoChilloutAnimator(AnimatorController originalAnimatorCon
639796

640797
for (int i = 0; i < existingLayers.Length; i++)
641798
{
642-
newLayers[newLayersIdx] = existingLayers[i];
643-
newLayersIdx++;
799+
if (existingLayers[i].stateMachine.states.Length > 0) { // Do not copy empty layers
800+
newLayers[newLayersIdx] = existingLayers[i];
801+
newLayersIdx++;
802+
}
644803
}
645804

646805
for (int i = 0; i < layersToMerge.Length; i++)
647806
{
648807
AnimatorControllerLayer layer = layersToMerge[i];
649808

650-
Debug.Log("Layer \"" + layer.name + "\" with " + layer.stateMachine.states.Length + " states");
809+
if (layer.stateMachine.states.Length > 0) { // Do not copy empty layers
810+
Debug.Log("Layer \"" + layer.name + "\" with " + layer.stateMachine.states.Length + " states");
651811

652-
ProcessStateMachine(layer.stateMachine);
812+
ProcessStateMachine(layer.stateMachine);
653813

654-
newLayers[newLayersIdx] = layer;
655-
newLayersIdx++;
814+
newLayers[newLayersIdx] = layer;
815+
newLayersIdx++;
816+
}
656817
}
657818

819+
Array.Resize(ref newLayers, newLayersIdx);
658820
chilloutAnimatorController.layers = newLayers;
659821

660822
Debug.Log("Merged");
@@ -721,7 +883,7 @@ void CreateEmptyChilloutAnimator()
721883
List<AnimatorControllerLayer> newLayers = new List<AnimatorControllerLayer>();
722884

723885
string[] allowedLayerNames;
724-
886+
725887
if (shouldDeleteCvrHandLayers) {
726888
Debug.Log("Deleting CVR hand layers...");
727889
allowedLayerNames = new string[] { "Locomotion/Emotes" };
@@ -781,12 +943,12 @@ void GetValuesFromVrcAvatar()
781943
}
782944

783945
int[] eyelidsBlendshapes = vrcAvatarDescriptor.customEyeLookSettings.eyelidsBlendshapes;
784-
946+
785947
if (eyelidsBlendshapes.Length >= 1 && eyelidsBlendshapes[0] != -1) {
786948
if (bodySkinnedMeshRenderer != null) {
787949
int blinkBlendshapeIdx = eyelidsBlendshapes[0];
788950
Mesh mesh = bodySkinnedMeshRenderer.sharedMesh;
789-
951+
790952
if (blinkBlendshapeIdx > mesh.blendShapeCount) {
791953
Debug.LogWarning("Could not use eyelid blendshape at index " + blinkBlendshapeIdx.ToString() + ": does not exist in mesh!");
792954
} else {
@@ -815,7 +977,7 @@ SkinnedMeshRenderer GetSkinnedMeshRendererInCVRAvatar() {
815977
string pathToSkinnedMeshRenderer = GetPathToGameObjectInsideAvatar(bodySkinnedMeshRenderer.gameObject);
816978

817979
Debug.Log("Path to body skinned mesh renderer: " + pathToSkinnedMeshRenderer);
818-
980+
819981
var match = cvrAvatar.transform.Find(pathToSkinnedMeshRenderer.Remove(0, 1));
820982

821983
if (match == null) {
@@ -831,7 +993,7 @@ SkinnedMeshRenderer GetSkinnedMeshRendererInCVRAvatar() {
831993
}
832994

833995
return skinnedMeshRenderer;
834-
}
996+
}
835997

836998
public static string GetPathToGameObjectInsideAvatar(GameObject obj)
837999
{

0 commit comments

Comments
 (0)