feat(params): Allow for MA Parameters to _not_ specify a default value (#636)

* feat(params): track whether a default value was explicitly set

* feat(params): improve default value resolution and error handling
This commit is contained in:
bd_ 2024-01-28 14:27:43 +09:00 committed by GitHub
parent 86fc302fa5
commit 1fc9c2d4ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 2348 additions and 97 deletions

View File

@ -4,7 +4,7 @@
"version": "3.4.2"
},
"nadena.dev.ndmf": {
"version": "1.3.0-rc.2"
"version": "1.3.0-rc.6"
}
},
"locked": {
@ -19,7 +19,7 @@
"dependencies": {}
},
"nadena.dev.ndmf": {
"version": "1.3.0-rc.2"
"version": "1.3.0-rc.6"
}
}
}

View File

@ -4,7 +4,7 @@
"version": "3.5.0"
},
"nadena.dev.ndmf": {
"version": "1.3.0-rc.2"
"version": "1.3.0-rc.6"
}
},
"locked": {
@ -19,7 +19,7 @@
"dependencies": {}
},
"nadena.dev.ndmf": {
"version": "1.3.0-rc.2"
"version": "1.3.0-rc.6"
}
}
}

View File

@ -0,0 +1,78 @@
using System.Globalization;
using nadena.dev.modular_avatar.core;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace nadena.dev.modular_avatar.core.editor
{
internal class DefaultValueField : VisualElement
{
public new class UxmlFactory : UxmlFactory<DefaultValueField, UxmlTraits>
{
}
private readonly TextField _visibleField;
private readonly FloatField _defaultValueField;
private readonly Toggle _hasExplicitDefaultSetField;
public DefaultValueField()
{
// Hidden binding elements
_defaultValueField = new FloatField();
_hasExplicitDefaultSetField = new Toggle();
_defaultValueField.RegisterValueChangedCallback(
evt => UpdateVisibleField(evt.newValue, _hasExplicitDefaultSetField.value));
_defaultValueField.bindingPath = nameof(ParameterConfig.defaultValue);
_hasExplicitDefaultSetField.RegisterValueChangedCallback(
evt => UpdateVisibleField(_defaultValueField.value, evt.newValue));
_hasExplicitDefaultSetField.bindingPath = nameof(ParameterConfig.hasExplicitDefaultValue);
_visibleField = new TextField();
_visibleField.RegisterValueChangedCallback(evt =>
{
if (string.IsNullOrWhiteSpace(evt.newValue))
{
_hasExplicitDefaultSetField.value = false;
_defaultValueField.value = 0;
}
else
{
_hasExplicitDefaultSetField.value = true;
_defaultValueField.value = float.Parse(evt.newValue, CultureInfo.InvariantCulture);
}
});
_defaultValueField.style.width = 0;
_defaultValueField.SetEnabled(false);
_hasExplicitDefaultSetField.style.width = 0;
_hasExplicitDefaultSetField.SetEnabled(false);
style.flexDirection = FlexDirection.Row;
Add(_visibleField);
Add(_defaultValueField);
Add(_hasExplicitDefaultSetField);
}
public void ManualBindProperty(SerializedProperty property)
{
_defaultValueField.BindProperty(property);
_hasExplicitDefaultSetField.BindProperty(property);
}
private void UpdateVisibleField(float value, bool hasExplicitValue)
{
if (Mathf.Abs(value) > 0.0000001)
{
hasExplicitValue = true;
}
var str = hasExplicitValue ? value.ToString(CultureInfo.InvariantCulture) : "";
_visibleField.SetValueWithoutNotify(str);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ea5245cc9b4342d180d30724e8838c9b
timeCreated: 1706340919

View File

@ -70,6 +70,25 @@ namespace nadena.dev.modular_avatar.core.editor.Parameters
remapTo.style.display = evt.changedProperty.boolValue ? DisplayStyle.None : DisplayStyle.Flex;
remapToPlaceholder.style.display = evt.changedProperty.boolValue ? DisplayStyle.Flex : DisplayStyle.None;
});
// This is a bit of a hack, but I'm not sure of another way to properly align property labels with a custom
// field, when we only want to manipulate a subset of fields on an object...
var defaultValueField = root.Q<VisualElement>("innerDefaultValueField"); // create ahead of time so it's bound...
// Then move it into the property field once the property field has created its inner controls
var defaultValueProp = root.Q<PropertyField>("defaultValueProp");
defaultValueProp.RegisterCallback<GeometryChangedEvent>(evt =>
{
var floatField = defaultValueProp.Q<FloatField>();
var innerField = floatField?.Q<DefaultValueField>();
if (floatField != null && innerField == null)
{
defaultValueField.RemoveFromHierarchy();
floatField.contentContainer.Add(defaultValueField);
}
});
return root;
}

View File

@ -1,7 +1,12 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:engine="UnityEditor.UIElements" editor="UnityEditor.UIElements" ma="nadena.dev.modular_avatar.core.editor" editor-extension-mode="False">
<ui:UXML
xmlns:ui="UnityEngine.UIElements"
xmlns:engine="UnityEditor.UIElements"
xmlns:ma="nadena.dev.modular_avatar.core.editor"
editor-extension-mode="False"
>
<ui:VisualElement name="MiniDisplay">
<ui:Label text="merge_parameter.ui.defaultValue" class="ndmf-tr"/>
<ui:FloatField binding-path="defaultValue"/>
<ma:DefaultValueField/>
<ui:Label text="merge_parameter.ui.saved" class="ndmf-tr"/>
<ui:Toggle binding-path="saved"/>
</ui:VisualElement>
@ -12,7 +17,15 @@
<engine:PropertyField binding-path="remapTo" label="merge_parameter.ui.remapTo" name="remapTo" class="ndmf-tr" />
<ui:TextField label="##merge_parameter.ui.remapTo" text="merge_parameter.ui.remapTo.automatic" name="remapToPlaceholder" enabled="false" class="ndmf-tr unity-base-field__aligned" />
<engine:PropertyField binding-path="defaultValue" name="defaultValue" label="merge_parameter.ui.defaultValue" class="ndmf-tr ParameterConfig__isPrefix_falseOnly"/>
<!-- this field is not visible until it's moved into the PropertyField below -->
<ma:DefaultValueField
name="innerDefaultValueField"
class="unity-base-field__input unity-property-field__input"
/>
<engine:PropertyField binding-path="defaultValue" name="defaultValueProp" label="merge_parameter.ui.defaultValue" class="ndmf-tr ParameterConfig__isPrefix_falseOnly">
</engine:PropertyField>
<engine:PropertyField binding-path="saved" label="merge_parameter.ui.saved" class="ndmf-tr ParameterConfig__isPrefix_falseOnly" />

View File

@ -28,6 +28,23 @@
flex-grow: 1;
}
#defaultValueProp > FloatField > FloatInput {
display: none;
}
#ParameterConfigRoot > DefaultValueField {
display: none;
}
#innerDefaultValueField {
flex-grow: 1;
}
DefaultValueField > TextField {
flex-grow: 1;
margin-left: 0;
}
#MiniDisplay {
flex-direction: row;
align-self: flex-end;
@ -37,14 +54,14 @@
align-self: center;
}
#MiniDisplay > FloatField {
#MiniDisplay > DefaultValueField {
max-width: 60px;
flex-grow: 0;
margin-right: 10px;
}
#MiniDisplay > FloatField TextElement {
#MiniDisplay > DefaultValueField TextElement {
margin-left: 0px;
}

View File

@ -141,15 +141,22 @@
"error.merge_armature.physbone_on_humanoid_bone": "[MA-0002] PhysBone component found on humanoid bone",
"error.merge_armature.physbone_on_humanoid_bone:hint": "Some Humanoid bones in the armature to merge are controlled by PhysBones, and can't be merged properly because its position is different from the corresponding Humanoid bone in the merge target. You should remove the PhysBones on those Humanoid bones in the armature to merge.",
"error.internal_error": "An internal error has occurred: {0}\nwhen processing:",
"error.internal_error": "[MA-9999] An internal error has occurred: {0}\nwhen processing:",
"error.merge_animator.param_type_mismatch": "[MA-0003] Parameter type mismatch",
"error.merge_animator.param_type_mismatch:description": "Parameter {0} has multiple types: {1} != {2}",
"error.rename_params.too_many_synced_params": "[MA-0004] Too many synced parameters",
"error.rename_params.too_many_synced_params:description": "You have too many synced parameters in your avatar. You have assigned {0} bits worth of parameters, but the limit is {1}",
"error.rename_params.type_conflict": "[MA-0006] Parameter type conflict",
"error.rename_params.type_conflict:description": "Parameter {0} has multiple types specified: {1} != {2}",
"error.replace_object.null_target": "[MA-0005] No target specified",
"error.rename_params.default_value_conflict": "[MA-0007] Default value conflict",
"error.rename_params.default_value_conflict:description": "Parameter {0} has multiple default values specified: {1} != {2}",
"error.rename_params.default_value_conflict:hint": "To avoid unpredictable behavior, leave the default value field blank in all but on MA Parameters component. If multiple values are present, Modular Avatar will select the first default value specified in the hierarchy order.",
"error.replace_object.null_target": "[MA-0008] No target specified",
"error.replace_object.null_target:hint": "Replace object needs a target object to replace. Try setting one.",
"validation.blendshape_sync.no_local_renderer": "[MA-1000] No renderer found on this object",

View File

@ -6,6 +6,7 @@ using System.Collections.Immutable;
using System.Linq;
using nadena.dev.modular_avatar.animation;
using nadena.dev.modular_avatar.editor.ErrorReporting;
using nadena.dev.ndmf;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
@ -15,6 +16,8 @@ using VRC.SDK3.Dynamics.Contact.Components;
using VRC.SDK3.Dynamics.PhysBone.Components;
using Object = UnityEngine.Object;
using UnityObject = UnityEngine.Object;
namespace nadena.dev.modular_avatar.core.editor
{
internal class RenameParametersHook
@ -25,21 +28,95 @@ namespace nadena.dev.modular_avatar.core.editor
private int internalParamIndex = 0;
private Dictionary<string, VRCExpressionParameters.Parameter> _syncedParams =
new Dictionary<string, VRCExpressionParameters.Parameter>();
class ParameterInfo
{
private static long encounterOrderCounter;
public ParameterConfig ResolvedParameter;
public List<UnityObject> TypeSources = new List<UnityObject>();
public List<UnityObject> DefaultSources = new List<UnityObject>();
public ImmutableHashSet<float> ConflictingValues = ImmutableHashSet<float>.Empty;
public ImmutableHashSet<ParameterSyncType> ConflictingSyncTypes = ImmutableHashSet<ParameterSyncType>.Empty;
public bool TypeConflict, DefaultValueConflict;
public long encounterOrder = encounterOrderCounter++;
public VRCExpressionParameters.ValueType? ValueType
{
get
{
switch (ResolvedParameter.syncType)
{
case ParameterSyncType.Bool: return VRCExpressionParameters.ValueType.Bool;
case ParameterSyncType.Float: return VRCExpressionParameters.ValueType.Float;
case ParameterSyncType.Int: return VRCExpressionParameters.ValueType.Int;
default: return null;
}
}
}
public void MergeSibling(ParameterInfo info)
{
MergeCommon(info);
if (ResolvedParameter.HasDefaultValue && info.ResolvedParameter.HasDefaultValue)
{
if (Math.Abs(ResolvedParameter.defaultValue - info.ResolvedParameter.defaultValue) > ParameterConfig.VALUE_EPSILON)
{
DefaultValueConflict = true;
ConflictingValues = ConflictingValues.Add(ResolvedParameter.defaultValue);
ConflictingValues = ConflictingValues.Add(info.ResolvedParameter.defaultValue);
}
}
}
public void MergeChild(ParameterInfo info)
{
MergeCommon(info);
if (!ResolvedParameter.HasDefaultValue && info.ResolvedParameter.HasDefaultValue)
{
ResolvedParameter.defaultValue = info.ResolvedParameter.defaultValue;
ResolvedParameter.hasExplicitDefaultValue = info.ResolvedParameter.hasExplicitDefaultValue;
}
}
void MergeCommon(ParameterInfo info)
{
if (ResolvedParameter.syncType == ParameterSyncType.NotSynced)
{
ResolvedParameter.syncType = info.ResolvedParameter.syncType;
} else if (ResolvedParameter.syncType != info.ResolvedParameter.syncType && info.ResolvedParameter.syncType != ParameterSyncType.NotSynced)
{
TypeConflict = true;
ConflictingSyncTypes = ConflictingSyncTypes
.Add(ResolvedParameter.syncType)
.Add(info.ResolvedParameter.syncType);
}
TypeSources.AddRange(info.TypeSources);
DefaultSources.AddRange(info.DefaultSources);
TypeConflict = TypeConflict || info.TypeConflict;
DefaultValueConflict = DefaultValueConflict || info.DefaultValueConflict;
ConflictingValues = ConflictingValues.Union(info.ConflictingValues);
ConflictingSyncTypes = ConflictingSyncTypes.Union(info.ConflictingSyncTypes);
encounterOrder = Math.Min(encounterOrder, info.encounterOrder);
}
}
public void OnPreprocessAvatar(GameObject avatar, BuildContext context)
{
_context = context;
_syncedParams.Clear();
var syncParams = WalkTree(avatar, ImmutableDictionary<string, string>.Empty, ImmutableDictionary<string, string>.Empty);
WalkTree(avatar, ImmutableDictionary<string, string>.Empty, ImmutableDictionary<string, string>.Empty);
SetExpressionParameters(avatar);
SetExpressionParameters(avatar, syncParams);
}
private void SetExpressionParameters(GameObject avatarRoot)
private void SetExpressionParameters(GameObject avatarRoot, ImmutableDictionary<string, ParameterInfo> syncParams)
{
var avatar = avatarRoot.GetComponent<VRCAvatarDescriptor>();
var expParams = avatar.expressionParameters;
@ -60,15 +137,61 @@ namespace nadena.dev.modular_avatar.core.editor
_context.SaveAsset(expParams);
var knownParams = expParams.parameters.Select(p => p.name).ToImmutableHashSet();
var parameters = expParams.parameters.ToList();
var parameters = expParams.parameters
.Select(p => ResolveParameter(p, syncParams))
.ToList();
foreach (var kvp in _syncedParams)
foreach (var kvp in syncParams)
{
var name = kvp.Key;
var param = kvp.Value;
if (!knownParams.Contains(name))
if (param.TypeConflict)
{
parameters.Add(param);
var t1 = param.ConflictingSyncTypes.First();
var t2 = param.ConflictingSyncTypes.Skip(1).First();
List<object> paramList = new List<object> { name, t1, t2 };
paramList.AddRange(param.TypeSources.Cast<object>());
BuildReport.Log(ErrorSeverity.Error, "error.rename_params.type_conflict", paramList.ToArray());
}
if (param.DefaultValueConflict)
{
var v1 = param.ConflictingValues.First();
var v2 = param.ConflictingValues.Skip(1).First();
List<object> paramList = new List<object> { name, v1, v2 };
paramList.AddRange(param.DefaultSources.Cast<object>());
BuildReport.Log(ErrorSeverity.NonFatal, "error.rename_params.default_value_conflict", paramList.ToArray());
}
if (!knownParams.Contains(name) && param.ResolvedParameter.syncType != ParameterSyncType.NotSynced)
{
var converted = new VRCExpressionParameters.Parameter();
converted.name = name;
switch (param.ResolvedParameter.syncType)
{
case ParameterSyncType.Bool:
converted.valueType = VRCExpressionParameters.ValueType.Bool;
break;
case ParameterSyncType.Float:
converted.valueType = VRCExpressionParameters.ValueType.Float;
break;
case ParameterSyncType.Int:
converted.valueType = VRCExpressionParameters.ValueType.Int;
break;
default:
throw new ArgumentException("Unknown parameter sync type " +
param.ResolvedParameter.syncType);
}
converted.networkSynced = !param.ResolvedParameter.localOnly;
converted.saved = param.ResolvedParameter.saved;
converted.defaultValue = param.ResolvedParameter.defaultValue;
parameters.Add(converted);
}
}
@ -86,16 +209,55 @@ namespace nadena.dev.modular_avatar.core.editor
avatar.expressionParameters = expParams;
}
private void WalkTree(
private VRCExpressionParameters.Parameter ResolveParameter(
VRCExpressionParameters.Parameter parameter,
ImmutableDictionary<string, ParameterInfo> syncParams
)
{
if (!syncParams.TryGetValue(parameter.name, out var info))
{
return parameter;
}
if (parameter.valueType != info.ValueType && info.ValueType != null)
{
var list = new List<object>
{
parameter.name,
parameter.valueType,
info.ValueType,
_context.AvatarDescriptor.expressionParameters,
};
list.AddRange(info.TypeSources);
BuildReport.Log(ErrorSeverity.Error, "error.rename_params.type_conflict",
parameter.name,
list
);
}
var newParameter = new VRCExpressionParameters.Parameter();
newParameter.defaultValue = info.ResolvedParameter.HasDefaultValue ? info.ResolvedParameter.defaultValue : parameter.defaultValue;
newParameter.name = parameter.name;
newParameter.valueType = parameter.valueType;
newParameter.networkSynced = parameter.networkSynced;
newParameter.saved = parameter.saved;
return newParameter;
}
private ImmutableDictionary<string, ParameterInfo> WalkTree(
GameObject obj,
ImmutableDictionary<string, string> remaps,
ImmutableDictionary<string, string> prefixRemaps
)
{
ImmutableDictionary<string, ParameterInfo> rv = ImmutableDictionary<string, ParameterInfo>.Empty;
var p = obj.GetComponent<ModularAvatarParameters>();
if (p != null)
{
BuildReport.ReportingObject(p, () => ApplyRemappings(p, ref remaps, ref prefixRemaps));
rv = BuildReport.ReportingObject(p, () => ApplyRemappings(p, ref remaps, ref prefixRemaps));
}
var willPurgeAnimators = false;
@ -217,10 +379,45 @@ namespace nadena.dev.modular_avatar.core.editor
});
}
var mergedChildParams = ImmutableDictionary<string, ParameterInfo>.Empty;
foreach (Transform child in obj.transform)
{
WalkTree(child.gameObject, remaps, prefixRemaps);
var childParams = WalkTree(child.gameObject, remaps, prefixRemaps);
foreach (var kvp in childParams)
{
var name = kvp.Key;
var info = kvp.Value;
if (mergedChildParams.TryGetValue(name, out var priorInfo))
{
priorInfo.MergeSibling(info);
}
else
{
mergedChildParams = mergedChildParams.SetItem(name, info);
}
}
}
foreach (var kvp in mergedChildParams)
{
var name = kvp.Key;
var info = kvp.Value;
var remappedName = remap(remaps, name);
info.ResolvedParameter.nameOrPrefix = remappedName;
if (rv.TryGetValue(remappedName, out var priorInfo))
{
priorInfo.MergeChild(info);
}
else
{
rv = rv.SetItem(remappedName, info);
}
}
return rv;
}
private void ProcessMenuInstaller(ModularAvatarMenuInstaller installer,
@ -401,11 +598,13 @@ namespace nadena.dev.modular_avatar.core.editor
t.conditions = conditions;
}
private void ApplyRemappings(ModularAvatarParameters p,
private ImmutableDictionary<string, ParameterInfo> ApplyRemappings(ModularAvatarParameters p,
ref ImmutableDictionary<string, string> remaps,
ref ImmutableDictionary<string, string> prefixRemaps
)
{
ImmutableDictionary<string, ParameterInfo> rv = ImmutableDictionary<string, ParameterInfo>.Empty;
foreach (var param in p.parameters)
{
bool doRemap = true;
@ -451,41 +650,34 @@ namespace nadena.dev.modular_avatar.core.editor
if (!param.isPrefix && param.syncType != ParameterSyncType.NotSynced)
{
AddSyncParam(param, remapTo);
if (rv.ContainsKey(remapTo))
{
BuildReport.Log(ErrorSeverity.NonFatal, "error.rename_params.duplicate_parameter", param.nameOrPrefix);
}
ParameterConfig parameterConfig = param;
parameterConfig.nameOrPrefix = remapTo;
parameterConfig.remapTo = null;
var info = new ParameterInfo()
{
ResolvedParameter = parameterConfig,
};
if (parameterConfig.syncType != ParameterSyncType.NotSynced)
{
info.TypeSources.Add(p);
}
if (parameterConfig.HasDefaultValue)
{
info.DefaultSources.Add(p);
}
rv = rv.SetItem(remapTo, info);
}
}
}
private void AddSyncParam(
ParameterConfig parameterConfig,
string remapTo
)
{
if (_syncedParams.ContainsKey(remapTo)) return;
VRCExpressionParameters.ValueType type;
switch (parameterConfig.syncType)
{
case ParameterSyncType.Bool:
type = VRCExpressionParameters.ValueType.Bool;
break;
case ParameterSyncType.Float:
type = VRCExpressionParameters.ValueType.Float;
break;
case ParameterSyncType.Int:
type = VRCExpressionParameters.ValueType.Int;
break;
default: throw new Exception("Unknown sync type " + parameterConfig.syncType);
}
_syncedParams[remapTo] = new VRCExpressionParameters.Parameter
{
name = remapTo,
valueType = type,
defaultValue = parameterConfig.defaultValue,
saved = parameterConfig.saved,
networkSynced = !parameterConfig.localOnly
};
return rv;
}
// This is generic to simplify remapping parameter driver fields, some of which are 'object's.

View File

@ -1,19 +1,33 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
namespace nadena.dev.modular_avatar.core
{
public struct ParameterInitialValue
{
public bool HasExplicitDefaultSet;
public float Value;
}
[Serializable]
public struct ParameterConfig
{
internal const float VALUE_EPSILON = 0.000001f;
public string nameOrPrefix;
public string remapTo;
public bool internalParameter, isPrefix;
public ParameterSyncType syncType;
public bool localOnly;
public float defaultValue;
public bool saved;
public bool hasExplicitDefaultValue;
public bool HasDefaultValue => hasExplicitDefaultValue || Mathf.Abs(defaultValue) > VALUE_EPSILON;
}
/**

View File

@ -26,18 +26,19 @@ Transform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3825275463613500755}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0.023681391, y: 1.0559628, z: -0.6872994}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 3646968714803193661}
- {fileID: 3646968713996568948}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!95 &3825275463613500750
Animator:
serializedVersion: 3
serializedVersion: 5
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
@ -50,10 +51,12 @@ Animator:
m_UpdateMode: 0
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_StabilizeFeet: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorControllerStateOnDisable: 0
m_KeepAnimatorStateOnDisable: 0
m_WriteDefaultValuesOnDisable: 0
--- !u!114 &3825275463613500753
MonoBehaviour:
m_ObjectHideFlags: 0
@ -322,40 +325,12 @@ MonoBehaviour:
contentType: 0
assetBundleUnityVersion:
fallbackStatus: 0
--- !u!114 &3825275463971368602
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4167925416990528462}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6fd7cab7d93b403280f2f9da978d8a4f, type: 3}
m_Name:
m_EditorClassIdentifier:
Bindings:
- ReferenceMesh:
referencePath: BaseMesh
Blendshape: shape_0
LocalBlendshape: shape_0_local
- ReferenceMesh:
referencePath: BaseMesh
Blendshape: shape_1
LocalBlendshape: shape_1
- ReferenceMesh:
referencePath: MissingMesh
Blendshape: missing_mesh_shape
LocalBlendshape: missing_mesh_shape
- ReferenceMesh:
referencePath:
Blendshape: missing_mesh_shape_2
LocalBlendshape: missing_mesh_shape_2
--- !u!1001 &3825275463173128406
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 3825275463613500751}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
@ -454,6 +429,9 @@ PrefabInstance:
value: BaseMesh
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 14ac2ad30c5d3444ca37f76cea5a7047, type: 3}
--- !u!4 &3646968714803193661 stripped
Transform:
@ -466,6 +444,7 @@ PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 3825275463613500751}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
@ -569,16 +548,52 @@ PrefabInstance:
value: SyncedMesh
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
type: 3}
insertIndex: -1
addedObject: {fileID: 3825275463971368602}
m_SourcePrefab: {fileID: 100100000, guid: 14ac2ad30c5d3444ca37f76cea5a7047, type: 3}
--- !u!1 &4167925416990528462 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
type: 3}
m_PrefabInstance: {fileID: 3825275463971368607}
m_PrefabAsset: {fileID: 0}
--- !u!4 &3646968713996568948 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
type: 3}
m_PrefabInstance: {fileID: 3825275463971368607}
m_PrefabAsset: {fileID: 0}
--- !u!1 &4167925416990528462 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: 14ac2ad30c5d3444ca37f76cea5a7047,
type: 3}
m_PrefabInstance: {fileID: 3825275463971368607}
m_PrefabAsset: {fileID: 0}
--- !u!114 &3825275463971368602
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4167925416990528462}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6fd7cab7d93b403280f2f9da978d8a4f, type: 3}
m_Name:
m_EditorClassIdentifier:
Bindings:
- ReferenceMesh:
referencePath: BaseMesh
Blendshape: shape_0
LocalBlendshape: shape_0_local
- ReferenceMesh:
referencePath: BaseMesh
Blendshape: shape_1
LocalBlendshape: shape_1
- ReferenceMesh:
referencePath: MissingMesh
Blendshape: missing_mesh_shape
LocalBlendshape: missing_mesh_shape
- ReferenceMesh:
referencePath:
Blendshape: missing_mesh_shape_2
LocalBlendshape: missing_mesh_shape_2

View File

@ -0,0 +1,15 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -340790334, guid: 67cc4cb7839cd3741b63733d5adf0442, type: 3}
m_Name: EmptyMenu
m_EditorClassIdentifier:
controls: []

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a595189001d956b429e278804db4f4b0
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,20 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -1506855854, guid: 67cc4cb7839cd3741b63733d5adf0442, type: 3}
m_Name: ParameterConflictTestParams
m_EditorClassIdentifier:
parameters:
- name: a
valueType: 1
saved: 0
defaultValue: 0.5
networkSynced: 0

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2f54979b614e8b049b6421109a0274c1
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9fc7cdd605ee9b44fb105a03cdb353c8
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,549 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &637676532601936319
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1045454656529665000}
- component: {fileID: 6087609344157592032}
m_Layer: 0
m_Name: ParentWins
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1045454656529665000
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 637676532601936319}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 4417116879698787718}
- {fileID: 3783466460454899559}
m_Father: {fileID: 9027350264122327824}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &6087609344157592032
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 637676532601936319}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71a96d4ea0c344f39e277d82035bf9bd, type: 3}
m_Name:
m_EditorClassIdentifier:
migrationCompleted: 0
parameters:
- nameOrPrefix: a
remapTo:
internalParameter: 0
isPrefix: 0
syncType: 2
localOnly: 0
defaultValue: 0
saved: 0
hasExplicitDefaultValue: 0
--- !u!1 &825679903131863735
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 9027350264122327824}
- component: {fileID: 6657619261121604472}
- component: {fileID: 381744585999711191}
- component: {fileID: 6018907921863585214}
m_Layer: 0
m_Name: ParameterResolution
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &9027350264122327824
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 825679903131863735}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -0.19918329, y: 0.8600853, z: -0.6144587}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1045454656529665000}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &6657619261121604472
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 825679903131863735}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 542108242, guid: 67cc4cb7839cd3741b63733d5adf0442, type: 3}
m_Name:
m_EditorClassIdentifier:
Name:
ViewPosition: {x: 0, y: 1.6, z: 0.2}
Animations: 0
ScaleIPD: 1
lipSync: 0
lipSyncJawBone: {fileID: 0}
lipSyncJawClosed: {x: 0, y: 0, z: 0, w: 1}
lipSyncJawOpen: {x: 0, y: 0, z: 0, w: 1}
VisemeSkinnedMesh: {fileID: 0}
MouthOpenBlendShapeName: Facial_Blends.Jaw_Down
VisemeBlendShapes: []
unityVersion:
portraitCameraPositionOffset: {x: 0, y: 0, z: 0}
portraitCameraRotationOffset: {x: 0, y: 1, z: 0, w: -0.00000004371139}
networkIDs: []
customExpressions: 1
expressionsMenu: {fileID: 11400000, guid: a595189001d956b429e278804db4f4b0, type: 2}
expressionParameters: {fileID: 11400000, guid: 2f54979b614e8b049b6421109a0274c1,
type: 2}
enableEyeLook: 0
customEyeLookSettings:
eyeMovement:
confidence: 0.5
excitement: 0.5
leftEye: {fileID: 0}
rightEye: {fileID: 0}
eyesLookingStraight:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
eyesLookingUp:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
eyesLookingDown:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
eyesLookingLeft:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
eyesLookingRight:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
eyelidType: 0
upperLeftEyelid: {fileID: 0}
upperRightEyelid: {fileID: 0}
lowerLeftEyelid: {fileID: 0}
lowerRightEyelid: {fileID: 0}
eyelidsDefault:
upper:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
lower:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
eyelidsClosed:
upper:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
lower:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
eyelidsLookingUp:
upper:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
lower:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
eyelidsLookingDown:
upper:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
lower:
linked: 1
left: {x: 0, y: 0, z: 0, w: 0}
right: {x: 0, y: 0, z: 0, w: 0}
eyelidsSkinnedMesh: {fileID: 0}
eyelidsBlendshapes:
customizeAnimationLayers: 0
baseAnimationLayers:
- isEnabled: 0
type: 0
animatorController: {fileID: 0}
mask: {fileID: 0}
isDefault: 1
- isEnabled: 0
type: 4
animatorController: {fileID: 0}
mask: {fileID: 0}
isDefault: 1
- isEnabled: 0
type: 5
animatorController: {fileID: 0}
mask: {fileID: 0}
isDefault: 1
specialAnimationLayers:
- isEnabled: 0
type: 6
animatorController: {fileID: 0}
mask: {fileID: 0}
isDefault: 1
- isEnabled: 0
type: 7
animatorController: {fileID: 0}
mask: {fileID: 0}
isDefault: 1
- isEnabled: 0
type: 8
animatorController: {fileID: 0}
mask: {fileID: 0}
isDefault: 1
AnimationPreset: {fileID: 0}
animationHashSet: []
autoFootsteps: 1
autoLocomotion: 1
collider_head:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_torso:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_footR:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_footL:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_handR:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_handL:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_fingerIndexL:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_fingerMiddleL:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_fingerRingL:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_fingerLittleL:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_fingerIndexR:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_fingerMiddleR:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_fingerRingR:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
collider_fingerLittleR:
isMirrored: 1
state: 0
transform: {fileID: 0}
radius: 0
height: 0
position: {x: 0, y: 0, z: 0}
rotation: {x: 0, y: 0, z: 0, w: 1}
--- !u!114 &381744585999711191
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 825679903131863735}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -1427037861, guid: 4ecd63eff847044b68db9453ce219299, type: 3}
m_Name:
m_EditorClassIdentifier:
launchedFromSDKPipeline: 0
completedSDKPipeline: 0
blueprintId:
contentType: 0
assetBundleUnityVersion:
fallbackStatus: 0
--- !u!95 &6018907921863585214
Animator:
serializedVersion: 5
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 825679903131863735}
m_Enabled: 1
m_Avatar: {fileID: 0}
m_Controller: {fileID: 0}
m_CullingMode: 0
m_UpdateMode: 0
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_StabilizeFeet: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorStateOnDisable: 0
m_WriteDefaultValuesOnDisable: 0
--- !u!1 &2058320306015137456
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6619961460191419643}
- component: {fileID: 2706654488088963333}
m_Layer: 0
m_Name: P (1)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6619961460191419643
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2058320306015137456}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 4417116879698787718}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2706654488088963333
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2058320306015137456}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71a96d4ea0c344f39e277d82035bf9bd, type: 3}
m_Name:
m_EditorClassIdentifier:
migrationCompleted: 0
parameters:
- nameOrPrefix: a
remapTo:
internalParameter: 0
isPrefix: 0
syncType: 2
localOnly: 0
defaultValue: 1
saved: 0
hasExplicitDefaultValue: 1
--- !u!1 &3544070647160969251
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3783466460454899559}
- component: {fileID: 8244320322899509705}
m_Layer: 0
m_Name: P (2)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3783466460454899559
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3544070647160969251}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1045454656529665000}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &8244320322899509705
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3544070647160969251}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71a96d4ea0c344f39e277d82035bf9bd, type: 3}
m_Name:
m_EditorClassIdentifier:
migrationCompleted: 0
parameters:
- nameOrPrefix: a
remapTo:
internalParameter: 0
isPrefix: 0
syncType: 2
localOnly: 0
defaultValue: 0
saved: 0
hasExplicitDefaultValue: 0
--- !u!1 &8528232542967234232
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4417116879698787718}
- component: {fileID: 1576133641690687503}
m_Layer: 0
m_Name: P
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4417116879698787718
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8528232542967234232}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 6619961460191419643}
m_Father: {fileID: 1045454656529665000}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1576133641690687503
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8528232542967234232}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71a96d4ea0c344f39e277d82035bf9bd, type: 3}
m_Name:
m_EditorClassIdentifier:
migrationCompleted: 0
parameters:
- nameOrPrefix: a
remapTo:
internalParameter: 0
isPrefix: 0
syncType: 2
localOnly: 0
defaultValue: 0.1
saved: 0
hasExplicitDefaultValue: 1

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: df145d36703065a40927386e65d5f1bf
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,10 +1,14 @@
#if MA_VRCSDK3_AVATARS
using System.Linq;
using nadena.dev.modular_avatar.core;
using nadena.dev.modular_avatar.core.editor;
using nadena.dev.ndmf;
using NUnit.Framework;
using UnityEngine;
using VRC.SDK3.Avatars.Components;
using VRC.SDK3.Avatars.ScriptableObjects;
using AvatarProcessor = nadena.dev.modular_avatar.core.editor.AvatarProcessor;
namespace modular_avatar_tests.RenameParametersTests
{
@ -62,6 +66,60 @@ namespace modular_avatar_tests.RenameParametersTests
AvatarProcessor.ProcessAvatar(avatar);
}
[Test]
public void TestParameterConflicts()
{
var prefab = CreatePrefab("ParameterConflicts.prefab");
var context = CreateContext(prefab);
var maContext = context.ActivateExtensionContext<ModularAvatarContext>().BuildContext;
var errors = ErrorReport.CaptureErrors(
() =>
{
using (new ObjectRegistryScope(new ObjectRegistry(prefab.transform)))
{
new RenameParametersHook().OnPreprocessAvatar(prefab, maContext);
}
});
var valueConflict = errors
.Select(e => e.TheError)
.Cast<SimpleError>()
.First(e => e.TitleKey == "error.rename_params.default_value_conflict");
Assert.AreEqual("a$$Internal_1", valueConflict.DetailsSubst[0]);
Assert.AreEqual("0", valueConflict.DetailsSubst[1]);
Assert.AreEqual("1", valueConflict.DetailsSubst[2]);
Assert.AreEqual("Conflict/P", valueConflict.References[0].Path);
Assert.AreEqual("Conflict/P (1)", valueConflict.References[1].Path);
var typeConflict = errors
.Select(e => e.TheError)
.Cast<SimpleError>()
.First(e => e.TitleKey == "error.rename_params.type_conflict");
Assert.AreEqual("a$$Internal_2", typeConflict.DetailsSubst[0]);
Assert.AreEqual("Int", typeConflict.DetailsSubst[1]);
Assert.AreEqual("Float", typeConflict.DetailsSubst[2]);
Assert.AreEqual("TypeConflict/P", typeConflict.References[0].Path);
Assert.AreEqual("TypeConflict/P (2)", typeConflict.References[1].Path);
}
[Test]
public void TestParameterResults()
{
var prefab = CreatePrefab("ParameterResolution.prefab");
AvatarProcessor.ProcessAvatar(prefab);
var expParams = prefab.GetComponent<VRCAvatarDescriptor>().expressionParameters;
Assert.AreEqual(expParams.parameters[0].name, "a");
Assert.IsTrue(Mathf.Abs(expParams.parameters[0].defaultValue - 0.1f) < 0.0001f);
}
}
}

View File

@ -16,6 +16,6 @@
},
"vpmDependencies": {
"com.vrchat.avatars": ">=3.2.0",
"nadena.dev.ndmf": ">=1.3.0-rc.2 <2.0.0-a"
"nadena.dev.ndmf": ">=1.3.0-rc.6 <2.0.0-a"
}
}