-
Notifications
You must be signed in to change notification settings - Fork 15
Shape key driver #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Shape key driver #28
Changes from all commits
9bbf0f6
86f5ad9
a79ec3b
7642652
5808b7a
d9bc246
3dad5a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| using UnityEditor; | ||
| using UnityEngine; | ||
|
|
||
| namespace BitStrap | ||
| { | ||
| [CustomPropertyDrawer(typeof(ShapeKeyDefinition))] | ||
| public class ShapeKeyDrawer : PropertyDrawer | ||
| { | ||
| string[] blendShapeNames = null; | ||
|
|
||
| public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | ||
| { | ||
| if (FindSkinnedMeshRenderer(property) == null) | ||
| return 0.0f; | ||
| return base.GetPropertyHeight(property, label); | ||
| } | ||
|
|
||
| public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
| { | ||
| PropertyDrawerHelper.LoadAttributeTooltip( this, label ); | ||
|
|
||
| var nameProperty = property.GetMemberProperty<ShapeKeyDefinition>( p => p.name ); | ||
|
|
||
| var skinnedMeshRenderer = FindSkinnedMeshRenderer(property); | ||
| if (skinnedMeshRenderer != null) | ||
| { | ||
| if (blendShapeNames == null) | ||
| { | ||
| var blendShapeCount = skinnedMeshRenderer.sharedMesh.blendShapeCount; | ||
| blendShapeNames = new string[blendShapeCount]; | ||
| for (int i = 0; i < blendShapeCount; i++) | ||
| { | ||
| blendShapeNames[i] = skinnedMeshRenderer.sharedMesh.GetBlendShapeName(i); | ||
| } | ||
| } | ||
|
|
||
| int currentIndex = System.Array.IndexOf(blendShapeNames, nameProperty.stringValue); | ||
|
|
||
| EditorGUI.BeginChangeCheck(); | ||
| currentIndex = EditorGUI.Popup( position, label.text, currentIndex, blendShapeNames ); | ||
|
|
||
| if( EditorGUI.EndChangeCheck() ) | ||
| { | ||
| nameProperty.stringValue = blendShapeNames[currentIndex]; | ||
| property.serializedObject.ApplyModifiedProperties(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private SkinnedMeshRenderer FindSkinnedMeshRenderer(SerializedProperty property) | ||
| { | ||
| var behaviour = property.serializedObject.targetObject as MonoBehaviour; | ||
| if (behaviour != null) | ||
| { | ||
| if (fieldInfo.GetAttribute<SkinnedMeshRendererFieldAttribute>(false) | ||
| .TryGet(out var skinnedMeshRendererFieldAttribute)) | ||
| { | ||
| var skinnedMeshRendererProperty = | ||
| property.serializedObject.FindProperty(skinnedMeshRendererFieldAttribute.skinnedMeshRendererFieldName); | ||
| if (skinnedMeshRendererProperty != null) | ||
| return skinnedMeshRendererProperty.objectReferenceValue as SkinnedMeshRenderer; | ||
| } | ||
| else | ||
| { | ||
| var skinnedMeshRendererProperty = property.serializedObject.FindProperty("skinnedMeshRenderer"); | ||
| if (skinnedMeshRendererProperty != null) | ||
| return skinnedMeshRendererProperty.objectReferenceValue as SkinnedMeshRenderer; | ||
| } | ||
| } | ||
|
|
||
| return null; | ||
| } | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,190 @@ | ||
| using UnityEditor; | ||
| using UnityEngine; | ||
|
|
||
| namespace BitStrap | ||
| { | ||
| [CustomPropertyDrawer(typeof(ShapeKeyPositionConfig))] | ||
| public class ShapeKeyPositionConfigDrawer : PropertyDrawer | ||
| { | ||
| public override float GetPropertyHeight( SerializedProperty property, GUIContent label ) | ||
| { | ||
| if (property.isExpanded) | ||
| return EditorHelper.SingleLineHeight * 8; | ||
|
|
||
| return EditorHelper.SingleLineHeight; | ||
| } | ||
| public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
| { | ||
| PropertyDrawerHelper.LoadAttributeTooltip( this, label ); | ||
| var rowFoldout = position.Row(0); | ||
| var rowDriverTransform = position.Row(1); | ||
| var rowPositionType = position.Row(2); | ||
| var rowAxis = position.Row(3); | ||
| var rowValues = position.Row(4); | ||
| var rowCurve = position.Row(5); | ||
|
|
||
| property.isExpanded = EditorGUI.Foldout(rowFoldout, property.isExpanded, label); | ||
|
|
||
| if (!property.isExpanded) | ||
| return; | ||
|
|
||
| using (IndentLevel.Do(EditorGUI.indentLevel + 1)) | ||
| using (LabelWidth.Do(128.0f)) | ||
| { | ||
| var driverTransformProperty = property.GetMemberProperty<ShapeKeyPositionConfig>( k => k.driverTransform); | ||
| EditorGUI.PropertyField(rowDriverTransform, driverTransformProperty); | ||
|
|
||
| var positionTypeProperty = property.GetMemberProperty<ShapeKeyPositionConfig>( k => k.positionType); | ||
| EditorGUI.PropertyField(rowPositionType, positionTypeProperty); | ||
|
|
||
| var startPropertyLabel = new GUIContent("Start Position"); | ||
| var endPropertyLabel = new GUIContent("End Position"); | ||
|
|
||
| switch ((ShapeKeyPositionConfig.PositionType)positionTypeProperty.enumValueIndex) | ||
| { | ||
| case ShapeKeyPositionConfig.PositionType.OneAxis: | ||
| { | ||
| var axisProperty = property.GetMemberProperty<ShapeKeyPositionConfig>( k => k.positionOneAxis); | ||
| var positionAxisLabel = new GUIContent("Axis"); | ||
| EditorGUI.PropertyField(rowAxis, axisProperty, positionAxisLabel); | ||
|
|
||
| rowValues.Left(rowValues.width * 0.5f, out var leftRect).Expand(out var rightRect); | ||
| leftRect.Right(26.0f, out var leftButtonRect).Left(-2.0f).Expand(out var outLeftRect); | ||
| rightRect.Right(26.0f, out var rightButtonRect).Left(-2.0f).Expand(out var outRightRect); | ||
|
|
||
| var startValueProperty = property.GetMemberProperty<ShapeKeyPositionConfig>( k => k.oneAxisStartPosition); | ||
| EditorGUI.PropertyField(outLeftRect, startValueProperty, startPropertyLabel); | ||
|
|
||
| if (GUI.Button(leftButtonRect, EditorGUIUtility.IconContent("d_Transform Icon"))) | ||
| { | ||
| SetOneAxis(axisProperty, startValueProperty, driverTransformProperty); | ||
| } | ||
|
|
||
| var endValueProperty = property.GetMemberProperty<ShapeKeyPositionConfig>( k => k.oneAxisEndPosition); | ||
| EditorGUI.PropertyField(outRightRect, endValueProperty, endPropertyLabel); | ||
|
|
||
| if (GUI.Button(rightButtonRect, EditorGUIUtility.IconContent("d_Transform Icon"))) | ||
| { | ||
| SetOneAxis(axisProperty, endValueProperty, driverTransformProperty); | ||
| } | ||
|
|
||
| break; | ||
| } | ||
| case ShapeKeyPositionConfig.PositionType.TwoAxis: | ||
| { | ||
| var axisProperty = property.GetMemberProperty<ShapeKeyPositionConfig>(k => k.positionTwoAxis); | ||
| var positionAxisLabel = new GUIContent("Axis"); | ||
| EditorGUI.PropertyField(rowAxis, axisProperty, positionAxisLabel); | ||
|
|
||
| rowValues.Left(rowValues.width * 0.5f, out var leftRect).Expand(out var rightRect); | ||
| leftRect.Right(26.0f, out var leftButtonRect).Left(-2.0f).Expand(out var outLeftRect); | ||
| rightRect.Right(26.0f, out var rightButtonRect).Left(-2.0f).Expand(out var outRightRect); | ||
|
|
||
| var startValueProperty = property.GetMemberProperty<ShapeKeyPositionConfig>( k => k.twoAxisStartPosition); | ||
| EditorGUI.PropertyField(outLeftRect, startValueProperty, startPropertyLabel); | ||
|
|
||
| if (GUI.Button(leftButtonRect, EditorGUIUtility.IconContent("d_Transform Icon"))) | ||
| { | ||
| SetTwoAxis(axisProperty, startValueProperty, driverTransformProperty); | ||
| } | ||
|
|
||
| var endValueProperty = property.GetMemberProperty<ShapeKeyPositionConfig>( k => k.twoAxisEndPosition); | ||
| EditorGUI.PropertyField(outRightRect, endValueProperty, endPropertyLabel); | ||
|
|
||
| if (GUI.Button(rightButtonRect, EditorGUIUtility.IconContent("d_Transform Icon"))) | ||
| { | ||
| SetTwoAxis(axisProperty, endValueProperty, driverTransformProperty); | ||
| } | ||
|
|
||
| break; | ||
| } | ||
| case ShapeKeyPositionConfig.PositionType.ThreeAxis: | ||
| { | ||
| rowValues.Left(rowValues.width * 0.5f, out var leftRect).Expand(out var rightRect); | ||
| leftRect.Right(26.0f, out var leftButtonRect).Left(-2.0f).Expand(out var outLeftRect); | ||
| rightRect.Right(26.0f, out var rightButtonRect).Left(-2.0f).Expand(out var outRightRect); | ||
|
|
||
| var startValueProperty = property.GetMemberProperty<ShapeKeyPositionConfig>(k => k.threeAxisStartPosition); | ||
| EditorGUI.PropertyField(outLeftRect, startValueProperty, startPropertyLabel); | ||
|
|
||
| if (GUI.Button(leftButtonRect, EditorGUIUtility.IconContent("d_Transform Icon"))) | ||
| { | ||
| SetThreeAxis(startValueProperty, driverTransformProperty); | ||
| } | ||
|
|
||
| var endValueProperty = property.GetMemberProperty<ShapeKeyPositionConfig>(k => k.threeAxisEndPosition); | ||
| EditorGUI.PropertyField(outRightRect, endValueProperty, endPropertyLabel); | ||
|
|
||
| if (GUI.Button(rightButtonRect, EditorGUIUtility.IconContent("d_Transform Icon"))) | ||
| { | ||
| SetThreeAxis(endValueProperty, driverTransformProperty); | ||
| } | ||
|
|
||
| break; | ||
| } | ||
| } | ||
| var interpolationCurve = property.GetMemberProperty<ShapeKeyRotationConfig>( k => k.interpolationCurve); | ||
| var curveLabel = new GUIContent("Curve"); | ||
|
|
||
| rowCurve.height = EditorHelper.SingleLineHeight * 3; | ||
| EditorGUI.PropertyField(rowCurve, interpolationCurve, curveLabel); | ||
| } | ||
| } | ||
|
|
||
| private void SetOneAxis(SerializedProperty axisProperty, SerializedProperty propertyToSet, | ||
| SerializedProperty driverTransformProperty) | ||
| { | ||
| var driverTransformPosition = ((Transform)driverTransformProperty.objectReferenceValue).position; | ||
|
|
||
| switch ((ShapeKeyPositionConfig.PositionOneAxis)axisProperty.enumValueIndex) | ||
| { | ||
| case ShapeKeyPositionConfig.PositionOneAxis.X: | ||
| propertyToSet.floatValue = driverTransformPosition.x; | ||
| break; | ||
| case ShapeKeyPositionConfig.PositionOneAxis.Y: | ||
| propertyToSet.floatValue = driverTransformPosition.y; | ||
| break; | ||
| case ShapeKeyPositionConfig.PositionOneAxis.Z: | ||
| propertyToSet.floatValue = driverTransformPosition.z; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| private void SetTwoAxis(SerializedProperty axisProperty, SerializedProperty propertyToSet, | ||
| SerializedProperty driverTransformProperty) | ||
| { | ||
| var driverTransformPosition = ((Transform)driverTransformProperty.objectReferenceValue).position; | ||
|
|
||
| var driverPos = driverTransformPosition; | ||
|
|
||
| switch ((ShapeKeyPositionConfig.PositionTwoAxis)axisProperty.enumValueIndex) | ||
| { | ||
| case ShapeKeyPositionConfig.PositionTwoAxis.XY: | ||
| propertyToSet.vector2Value = new Vector2(driverPos.x, driverPos.y); | ||
| break; | ||
| case ShapeKeyPositionConfig.PositionTwoAxis.XZ: | ||
| propertyToSet.vector2Value = new Vector2(driverPos.x, driverPos.z); | ||
| break; | ||
| case ShapeKeyPositionConfig.PositionTwoAxis.YX: | ||
| propertyToSet.vector2Value = new Vector2(driverPos.y, driverPos.x); | ||
| break; | ||
| case ShapeKeyPositionConfig.PositionTwoAxis.YZ: | ||
| propertyToSet.vector2Value = new Vector2(driverPos.y, driverPos.z); | ||
| break; | ||
| case ShapeKeyPositionConfig.PositionTwoAxis.ZY: | ||
| propertyToSet.vector2Value = new Vector2(driverPos.z, driverPos.y); | ||
| break; | ||
| case ShapeKeyPositionConfig.PositionTwoAxis.ZX: | ||
| propertyToSet.vector2Value = new Vector2(driverPos.z, driverPos.x); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| private void SetThreeAxis(SerializedProperty propertyToSet, SerializedProperty driverTransformProperty) | ||
| { | ||
| var driverTransformPosition = ((Transform)driverTransformProperty.objectReferenceValue).position; | ||
|
|
||
| propertyToSet.vector3Value = driverTransformPosition; | ||
| } | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| using UnityEditor; | ||
| using UnityEngine; | ||
|
|
||
| namespace BitStrap | ||
| { | ||
| [CustomPropertyDrawer(typeof(ShapeKeyRecipe))] | ||
| public class ShapeKeyRecipeDrawer : PropertyDrawer | ||
| { | ||
| public override float GetPropertyHeight( SerializedProperty property, GUIContent label ) | ||
| { | ||
| return EditorHelper.SingleLineHeight * 10; | ||
| } | ||
|
|
||
| public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
| { | ||
| var rowShapeKeyDefinition = position.Row(0); | ||
| var rowDriverType = position.Row(1); | ||
| var rowShapeKeyConfigs = position.Row(2); | ||
|
|
||
| var shapeKeyProperty = property.GetMemberProperty<ShapeKeyRecipe>( k => k.shapeKeyDefinition); | ||
| EditorGUI.PropertyField(rowShapeKeyDefinition, shapeKeyProperty); | ||
|
|
||
| var driverTypeProperty = property.GetMemberProperty<ShapeKeyRecipe>( k => k.driverType); | ||
| EditorGUI.PropertyField(rowDriverType, driverTypeProperty); | ||
|
|
||
| switch ((ShapeKeyRecipe.DriverType)driverTypeProperty.enumValueIndex) | ||
| { | ||
| case ShapeKeyRecipe.DriverType.Rotation: | ||
| { | ||
| var shapeKeyRotationProperty = | ||
| property.GetMemberProperty<ShapeKeyRecipe>(k => k.shapeKeyRotationConfig); | ||
| EditorGUI.PropertyField(rowShapeKeyConfigs, shapeKeyRotationProperty); | ||
| break; | ||
| } | ||
| case ShapeKeyRecipe.DriverType.Position: | ||
| { | ||
| var shapeKeyPositionProperty = | ||
| property.GetMemberProperty<ShapeKeyRecipe>(k => k.shapeKeyPositionConfig); | ||
| EditorGUI.PropertyField(rowShapeKeyConfigs, shapeKeyPositionProperty); | ||
| break; | ||
| } | ||
| // TODO: implement | ||
| // case ShapeKeyRecipe.DriverType.MecanimParameter: | ||
| // break; | ||
| // case ShapeKeyRecipe.DriverType.Callback: | ||
| // break; | ||
| } | ||
|
|
||
| } | ||
| } | ||
| } | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dá pra tirar esses códigos comentados? ou é pra não se esquecer depois de implementar?
se for lembrete, talvez seja uma boa adicionar um
// TODO: implementou parecidoThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adicionei o TODO aqui