init free 2.1.3
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "Nova.UIControls.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:552447fb6cdb3d34b969d73c1b33b7d8",
|
||||
"GUID:d3646cb6c22de2d4e9ab342c87024f8e"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.modules.animation",
|
||||
"expression": "1.0.0",
|
||||
"define": "PACKAGE_ANIMATION"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce30efaf10a885744981d3edb9921a2c
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NovaSamples.Editor
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(ShowIfAttribute))]
|
||||
public class ShowIfPropertyDrawer : PropertyDrawer
|
||||
{
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) => ShouldShow(property, attribute as ShowIfAttribute) ? base.GetPropertyHeight(property, label) : 0;
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if (!ShouldShow(property, attribute as ShowIfAttribute))
|
||||
{
|
||||
// Don't show the field if false
|
||||
return;
|
||||
}
|
||||
|
||||
// Show the field
|
||||
EditorGUI.PropertyField(position, property, label);
|
||||
}
|
||||
|
||||
private static bool ShouldShow(SerializedProperty property, ShowIfAttribute showIf)
|
||||
{
|
||||
SerializedProperty fieldToCheck;
|
||||
|
||||
try
|
||||
{
|
||||
fieldToCheck = property.serializedObject.FindProperty(showIf.compareToFieldName);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
|
||||
// Don't hide things if something's broken
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (showIf.visibleValue)
|
||||
{
|
||||
case bool boolValue:
|
||||
return boolValue == fieldToCheck.boolValue;
|
||||
case float floatValue:
|
||||
return floatValue == fieldToCheck.floatValue;
|
||||
case int intValue:
|
||||
return intValue == fieldToCheck.intValue;
|
||||
case string stringValue:
|
||||
return stringValue == fieldToCheck.stringValue;
|
||||
case System.Enum enumValue:
|
||||
return enumValue.GetHashCode() == fieldToCheck.intValue;
|
||||
default:
|
||||
Debug.LogError("Not a supported ShowIf comparison type. Only string, bool, float, int, and enum types are currently supported.", property.serializedObject.targetObject);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfbaed32ff5492447bab22bc54f2d946
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,325 @@
|
||||
using Nova;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
#if PACKAGE_ANIMATION
|
||||
using UnityEditor.Animations;
|
||||
#endif
|
||||
using UnityEngine;
|
||||
|
||||
namespace NovaSamples.UIControls.Editor
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(UIControlVisuals), true)]
|
||||
public class UIControlVisualsPropertyDrawer : PropertyDrawer
|
||||
{
|
||||
private static readonly GUIContent CreateAnimationsLabel = EditorGUIUtility.TrTextContent("Create Animations", "Creates all required animation assets and adds an Animator component if it doesn't already exist.");
|
||||
private const string CreateAnimatorControllerWindowTitle = "New Animation Contoller";
|
||||
private const string CreateAnimatorControllerMessage = "Create a new animator for the game object '{0}':";
|
||||
private const string AnimatorControllerAssetExtension = "controller";
|
||||
|
||||
// Can't use nameof here because the serialized
|
||||
// field is private, which makes it inaccessible.
|
||||
private const string TransitionTargetName = "transitionTarget";
|
||||
|
||||
private const string TransitionTypeName = nameof(UIControlVisuals.TransitionType);
|
||||
private const string TransitionDurationName = nameof(UIControlVisuals.TransitionDuration);
|
||||
|
||||
private const string DefaultColorName = nameof(UIControlVisuals.DefaultColor);
|
||||
private const string HoveredColorName = nameof(UIControlVisuals.HoveredColor);
|
||||
private const string PressedColorName = nameof(UIControlVisuals.PressedColor);
|
||||
|
||||
private const string SpritesName = nameof(UIControlVisuals.Sprites);
|
||||
private const string AnimationsName = nameof(UIControlVisuals.Animations);
|
||||
|
||||
// The colors + transition duration
|
||||
private const int NumberOfColorStates = 3;
|
||||
|
||||
private static readonly string[] ColorChangeFields = new string[] { TransitionTargetName, DefaultColorName, HoveredColorName, PressedColorName, TransitionDurationName };
|
||||
private static readonly string[] SpriteSwapFields = new string[] { TransitionTargetName, SpritesName };
|
||||
private static readonly string[] AnimationFields = new string[] { AnimationsName };
|
||||
|
||||
private static readonly HashSet<string> BaseFields = new HashSet<string>()
|
||||
{
|
||||
TransitionDurationName,
|
||||
TransitionTargetName,
|
||||
TransitionTypeName,
|
||||
DefaultColorName,
|
||||
HoveredColorName,
|
||||
PressedColorName,
|
||||
SpritesName,
|
||||
AnimationsName,
|
||||
};
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if (!property.isExpanded)
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
|
||||
float totalPropertyHeight = EditorGUI.GetPropertyHeight(property, includeChildren: true);
|
||||
|
||||
SerializedProperty transitionTypeProp = property.FindPropertyRelative(TransitionTypeName);
|
||||
|
||||
TransitionType transitionType = (TransitionType)transitionTypeProp.intValue;
|
||||
|
||||
float lineHeight = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
|
||||
float transitionTargetHeight = lineHeight;
|
||||
float transitionDurationHeight = lineHeight;
|
||||
float expectedSpritesHeight = GetFieldHeight(property, SpritesName);
|
||||
float actualSpritesHeight = lineHeight * GetChildPropertyCount(property, SpritesName);
|
||||
float expectedAnimationsHeight = GetFieldHeight(property, AnimationsName);
|
||||
float actualAnimationsHeight = lineHeight * GetChildPropertyCount(property, AnimationsName);
|
||||
float colorsHeight = NumberOfColorStates * lineHeight;
|
||||
|
||||
totalPropertyHeight -= colorsHeight + expectedSpritesHeight + expectedAnimationsHeight + transitionTargetHeight;
|
||||
|
||||
if (!transitionTypeProp.hasMultipleDifferentValues)
|
||||
{
|
||||
switch (transitionType)
|
||||
{
|
||||
case TransitionType.ColorChange:
|
||||
totalPropertyHeight += colorsHeight + transitionTargetHeight + transitionDurationHeight;
|
||||
break;
|
||||
case TransitionType.SpriteSwap:
|
||||
totalPropertyHeight += actualSpritesHeight + transitionTargetHeight;
|
||||
break;
|
||||
case TransitionType.Animation:
|
||||
totalPropertyHeight += actualAnimationsHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return totalPropertyHeight;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
position = DrawProperty(position, property, label);
|
||||
|
||||
if (!property.isExpanded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (EditorGUI.IndentLevelScope scope = new EditorGUI.IndentLevelScope(1))
|
||||
{
|
||||
position = DrawAllChildClassFields(position, property.Copy());
|
||||
|
||||
SerializedProperty transitionTypeProp = property.FindPropertyRelative(TransitionTypeName);
|
||||
|
||||
position = DrawProperty(position, transitionTypeProp);
|
||||
|
||||
TransitionType transitionType = (TransitionType)transitionTypeProp.intValue;
|
||||
|
||||
if (transitionTypeProp.hasMultipleDifferentValues)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ItemView itemView = property.serializedObject.targetObject as ItemView;
|
||||
|
||||
switch (transitionType)
|
||||
{
|
||||
case TransitionType.ColorChange:
|
||||
position = DrawFields(position, property, ColorChangeFields);
|
||||
break;
|
||||
case TransitionType.SpriteSwap:
|
||||
position = DrawFields(position, property, SpriteSwapFields);
|
||||
break;
|
||||
case TransitionType.Animation:
|
||||
position = DrawFields(position, property, AnimationFields);
|
||||
#if PACKAGE_ANIMATION
|
||||
if (property.serializedObject.targetObjects.Length == 1)
|
||||
{
|
||||
DrawCreateAnimationsButton(itemView);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Rect DrawAllChildClassFields(Rect position, SerializedProperty property)
|
||||
{
|
||||
bool isBaseField = false;
|
||||
|
||||
while (property.NextVisible(!isBaseField))
|
||||
{
|
||||
isBaseField = BaseFields.Contains(property.name);
|
||||
|
||||
if (isBaseField)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
position = DrawProperty(position, property);
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
private static Rect DrawFields(Rect position, SerializedProperty property, string[] relativePropertyNames)
|
||||
{
|
||||
foreach (string relativePropertyName in relativePropertyNames)
|
||||
{
|
||||
SerializedProperty relativeProperty = property.FindPropertyRelative(relativePropertyName);
|
||||
|
||||
if (relativeProperty.hasVisibleChildren)
|
||||
{
|
||||
IEnumerator iterator = relativeProperty.GetEnumerator();
|
||||
|
||||
while (iterator.MoveNext())
|
||||
{
|
||||
position = DrawProperty(position, iterator.Current as SerializedProperty);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
position = DrawProperty(position, relativeProperty);
|
||||
}
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
private static Rect DrawProperty(Rect position, SerializedProperty property, GUIContent label = null)
|
||||
{
|
||||
position.height = EditorGUI.GetPropertyHeight(property, false);
|
||||
|
||||
EditorGUI.PropertyField(position, property, label, includeChildren: false);
|
||||
|
||||
position.y = position.yMax + EditorGUIUtility.standardVerticalSpacing;
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
private static float GetFieldHeight(SerializedProperty property, string relativePropertyName)
|
||||
{
|
||||
SerializedProperty relativeProperty = property.FindPropertyRelative(relativePropertyName);
|
||||
|
||||
return EditorGUI.GetPropertyHeight(relativeProperty, includeChildren: relativeProperty.isExpanded) + EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
|
||||
private static int GetChildPropertyCount(SerializedProperty property, string relativePropertyName)
|
||||
{
|
||||
SerializedProperty relativeProperty = property.FindPropertyRelative(relativePropertyName);
|
||||
|
||||
if (!relativeProperty.hasVisibleChildren)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int childCount = 0;
|
||||
|
||||
foreach (var child in relativeProperty)
|
||||
{
|
||||
childCount++;
|
||||
}
|
||||
|
||||
return childCount;
|
||||
}
|
||||
|
||||
#if PACKAGE_ANIMATION
|
||||
private static void DrawCreateAnimationsButton(ItemView itemView)
|
||||
{
|
||||
if (itemView == null || !itemView.TryGetVisuals(out UIControlVisuals controlVisuals))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (itemView.TryGetComponent(out Animator animator) && animator.runtimeAnimatorController != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Rect buttonPosition = EditorGUILayout.GetControlRect();
|
||||
buttonPosition.xMin += EditorGUIUtility.labelWidth;
|
||||
|
||||
AnimationStates animationStates = controlVisuals.Animations;
|
||||
|
||||
if (!GUI.Button(buttonPosition, CreateAnimationsLabel))
|
||||
{
|
||||
// Button wasn't clicked
|
||||
return;
|
||||
}
|
||||
|
||||
AnimatorController controller = CreateAnimatorControllerAsset(animationStates, itemView);
|
||||
|
||||
if (controller == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (animator == null)
|
||||
{
|
||||
animator = Undo.AddComponent<Animator>(itemView.gameObject);
|
||||
}
|
||||
|
||||
AnimatorController.SetAnimatorController(animator, controller);
|
||||
}
|
||||
|
||||
private static AnimatorController CreateAnimatorControllerAsset(AnimationStates animations, ItemView target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Where should we create the controller?
|
||||
string path = GetSaveControllerPath(target);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get animation names
|
||||
string defaultAnimation = string.IsNullOrWhiteSpace(animations.DefaultAnimation) ? AnimationStates.DefaultStates.DefaultAnimation : animations.DefaultAnimation;
|
||||
string hoveredAnimation = string.IsNullOrWhiteSpace(animations.HoveredAnimation) ? AnimationStates.DefaultStates.HoveredAnimation : animations.HoveredAnimation;
|
||||
string pressedAnimation = string.IsNullOrWhiteSpace(animations.PressedAnimation) ? AnimationStates.DefaultStates.PressedAnimation : animations.PressedAnimation;
|
||||
|
||||
// Create controller and hook up transitions.
|
||||
AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath(path);
|
||||
|
||||
CreateAnimationForController(controller, defaultAnimation);
|
||||
CreateAnimationForController(controller, hoveredAnimation);
|
||||
CreateAnimationForController(controller, pressedAnimation);
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.ImportAsset(path);
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
private static AnimationClip CreateAnimationForController(AnimatorController controller, string animationName)
|
||||
{
|
||||
// Create the animation
|
||||
AnimationClip animation = AnimatorController.AllocateAnimatorClip(animationName);
|
||||
AssetDatabase.AddObjectToAsset(animation, controller);
|
||||
|
||||
// Create a state in the animator controller for this animation
|
||||
AnimatorState state = controller.AddMotion(animation);
|
||||
|
||||
// Add a transition property
|
||||
controller.AddParameter(animationName, AnimatorControllerParameterType.Trigger);
|
||||
|
||||
// Add an any state transition
|
||||
AnimatorStateMachine stateMachine = controller.layers[0].stateMachine;
|
||||
AnimatorStateTransition transition = stateMachine.AddAnyStateTransition(state);
|
||||
transition.AddCondition(AnimatorConditionMode.If, 0, animationName);
|
||||
|
||||
return animation;
|
||||
}
|
||||
|
||||
private static string GetSaveControllerPath(MonoBehaviour target)
|
||||
{
|
||||
string objectName = target.gameObject.name;
|
||||
|
||||
string message = string.Format(CreateAnimatorControllerMessage, objectName);
|
||||
|
||||
return EditorUtility.SaveFilePanelInProject(CreateAnimatorControllerWindowTitle, objectName, AnimatorControllerAssetExtension, message);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9aaa28d05886d1146a43e79607000d41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user