Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 05efde5001 | |||
| f275c468ec | |||
| c141acf129 | |||
| fdc0a286c8 | |||
| e5627b1caf | |||
| 5f54c254f3 | |||
| b8c11e7836 | |||
| f656cd0f12 | |||
| f69bfc6773 | |||
| 7f424c0f97 | |||
| 2934eea84e | |||
| f781ad7373 | |||
| e5a5157b3c | |||
| 69830f3583 | |||
| c9b5193e51 | |||
| a8bcece352 | |||
| 70f2cdaf16 | |||
| 97c4e632bc | |||
| 93d7e13f62 | |||
| f522e0f285 | |||
| d061f748b8 | |||
| afb3089943 | |||
| d2d5c8ed52 | |||
| 2455229944 | |||
| 6ae47efa1d | |||
| 343d930155 | |||
| 1e52b89dd2 | |||
| ba83546f0a | |||
| 15a627bd48 | |||
| e6f57ed763 | |||
| 59da3868b1 | |||
| 65b0076c95 | |||
| 360c800b25 | |||
| cdbc2daf21 | |||
| 5d43ced8cc |
@@ -28,9 +28,13 @@ jobs:
|
|||||||
|
|
||||||
# Build
|
# Build
|
||||||
- name: Build .unitypackage
|
- name: Build .unitypackage
|
||||||
uses: game-ci/unity-builder@v2
|
uses: game-ci/unity-builder@v4
|
||||||
|
env:
|
||||||
|
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
with:
|
with:
|
||||||
unityVersion: 2020.3.8f1
|
unityVersion: 2021.3.29f1
|
||||||
buildMethod: MackySoft.PackageTools.Editor.UnityPackageExporter.Export
|
buildMethod: MackySoft.PackageTools.Editor.UnityPackageExporter.Export
|
||||||
|
|
||||||
# Upload
|
# Upload
|
||||||
|
|||||||
@@ -61,10 +61,10 @@ jobs:
|
|||||||
needs: [update-packagejson]
|
needs: [update-packagejson]
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
unity: ["2020.3.8f1"]
|
unity: ["2021.3.29f1"]
|
||||||
include:
|
include:
|
||||||
- unityVersion: 2020.3.8f1
|
- unityVersion: 2021.3.29f1
|
||||||
license: UNITY_LICENSE_2020
|
license: UNITY_LICENSE
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
steps:
|
steps:
|
||||||
@@ -74,9 +74,11 @@ jobs:
|
|||||||
ref: ${{ needs.update-packagejson.outputs.sha }}
|
ref: ${{ needs.update-packagejson.outputs.sha }}
|
||||||
|
|
||||||
- name: Export unitypackage
|
- name: Export unitypackage
|
||||||
uses: game-ci/unity-builder@v2
|
uses: game-ci/unity-builder@v4
|
||||||
env:
|
env:
|
||||||
UNITY_LICENSE: ${{ secrets[matrix.license] }}
|
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
|
||||||
|
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
|
||||||
|
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
|
||||||
with:
|
with:
|
||||||
projectPath: .
|
projectPath: .
|
||||||
unityVersion: ${{ matrix.unityVersion }}
|
unityVersion: ${{ matrix.unityVersion }}
|
||||||
|
|||||||
+107
@@ -0,0 +1,107 @@
|
|||||||
|
// NOTE: managedReferenceValue getter is available only in Unity 2021.3 or later.
|
||||||
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
using System;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace MackySoft.SerializeReferenceExtensions.Editor
|
||||||
|
{
|
||||||
|
public static class ManagedReferenceContextualPropertyMenu
|
||||||
|
{
|
||||||
|
|
||||||
|
const string kCopiedPropertyPathKey = "SerializeReferenceExtensions.CopiedPropertyPath";
|
||||||
|
const string kClipboardKey = "SerializeReferenceExtensions.CopyAndPasteProperty";
|
||||||
|
|
||||||
|
static readonly GUIContent kPasteContent = new GUIContent("Paste Property");
|
||||||
|
static readonly GUIContent kNewInstanceContent = new GUIContent("New Instance");
|
||||||
|
static readonly GUIContent kResetAndNewInstanceContent = new GUIContent("Reset and New Instance");
|
||||||
|
|
||||||
|
[InitializeOnLoadMethod]
|
||||||
|
static void Initialize ()
|
||||||
|
{
|
||||||
|
EditorApplication.contextualPropertyMenu += OnContextualPropertyMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnContextualPropertyMenu (GenericMenu menu, SerializedProperty property)
|
||||||
|
{
|
||||||
|
if (property.propertyType == SerializedPropertyType.ManagedReference)
|
||||||
|
{
|
||||||
|
// NOTE: When the callback function is called, the SerializedProperty is rewritten to the property that was being moused over at the time,
|
||||||
|
// so a new SerializedProperty instance must be created.
|
||||||
|
SerializedProperty clonedProperty = property.Copy();
|
||||||
|
|
||||||
|
menu.AddItem(new GUIContent($"Copy \"{property.propertyPath}\" property"), false, Copy, clonedProperty);
|
||||||
|
|
||||||
|
string copiedPropertyPath = SessionState.GetString(kCopiedPropertyPathKey, string.Empty);
|
||||||
|
if (!string.IsNullOrEmpty(copiedPropertyPath))
|
||||||
|
{
|
||||||
|
menu.AddItem(new GUIContent($"Paste \"{copiedPropertyPath}\" property"), false, Paste, clonedProperty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menu.AddDisabledItem(kPasteContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.AddSeparator("");
|
||||||
|
|
||||||
|
bool hasInstance = clonedProperty.managedReferenceValue != null;
|
||||||
|
if (hasInstance)
|
||||||
|
{
|
||||||
|
menu.AddItem(kNewInstanceContent, false, NewInstance, clonedProperty);
|
||||||
|
menu.AddItem(kResetAndNewInstanceContent, false, ResetAndNewInstance, clonedProperty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menu.AddDisabledItem(kNewInstanceContent);
|
||||||
|
menu.AddDisabledItem(kResetAndNewInstanceContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Copy (object customData)
|
||||||
|
{
|
||||||
|
SerializedProperty property = (SerializedProperty)customData;
|
||||||
|
string json = JsonUtility.ToJson(property.managedReferenceValue);
|
||||||
|
SessionState.SetString(kCopiedPropertyPathKey, property.propertyPath);
|
||||||
|
SessionState.SetString(kClipboardKey, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Paste (object customData)
|
||||||
|
{
|
||||||
|
SerializedProperty property = (SerializedProperty)customData;
|
||||||
|
string json = SessionState.GetString(kClipboardKey, string.Empty);
|
||||||
|
if (string.IsNullOrEmpty(json))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Undo.RecordObject(property.serializedObject.targetObject, "Paste Property");
|
||||||
|
JsonUtility.FromJsonOverwrite(json, property.managedReferenceValue);
|
||||||
|
property.serializedObject.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NewInstance (object customData)
|
||||||
|
{
|
||||||
|
SerializedProperty property = (SerializedProperty)customData;
|
||||||
|
string json = JsonUtility.ToJson(property.managedReferenceValue);
|
||||||
|
|
||||||
|
Undo.RecordObject(property.serializedObject.targetObject, "New Instance");
|
||||||
|
property.managedReferenceValue = JsonUtility.FromJson(json, property.managedReferenceValue.GetType());
|
||||||
|
property.serializedObject.ApplyModifiedProperties();
|
||||||
|
|
||||||
|
Debug.Log($"Create new instance of \"{property.propertyPath}\".");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResetAndNewInstance (object customData)
|
||||||
|
{
|
||||||
|
SerializedProperty property = (SerializedProperty)customData;
|
||||||
|
|
||||||
|
Undo.RecordObject(property.serializedObject.targetObject, "Reset and New Instance");
|
||||||
|
property.managedReferenceValue = Activator.CreateInstance(property.managedReferenceValue.GetType());
|
||||||
|
property.serializedObject.ApplyModifiedProperties();
|
||||||
|
|
||||||
|
Debug.Log($"Reset property and created new instance of \"{property.propertyPath}\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 734d3eb8da4785b49919aea6db62d877
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
+24
-4
@@ -2,14 +2,34 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace MackySoft.SerializeReferenceExtensions.Editor
|
||||||
|
{
|
||||||
|
|
||||||
namespace MackySoft.SerializeReferenceExtensions.Editor {
|
|
||||||
public static class ManagedReferenceUtility {
|
public static class ManagedReferenceUtility {
|
||||||
|
|
||||||
public static object SetManagedReference (this SerializedProperty property,Type type) {
|
public static object SetManagedReference (this SerializedProperty property,Type type) {
|
||||||
object obj = (type != null) ? Activator.CreateInstance(type) : null;
|
object result = null;
|
||||||
property.managedReferenceValue = obj;
|
|
||||||
return obj;
|
#if UNITY_2021_3_OR_NEWER
|
||||||
|
// NOTE: managedReferenceValue getter is available only in Unity 2021.3 or later.
|
||||||
|
if ((type != null) && (property.managedReferenceValue != null))
|
||||||
|
{
|
||||||
|
// Restore an previous values from json.
|
||||||
|
string json = JsonUtility.ToJson(property.managedReferenceValue);
|
||||||
|
result = JsonUtility.FromJson(json, type);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
result = (type != null) ? Activator.CreateInstance(type) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
property.managedReferenceValue = result;
|
||||||
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type GetType (string typeName) {
|
public static Type GetType (string typeName) {
|
||||||
|
|||||||
+34
-2
@@ -25,6 +25,8 @@ namespace MackySoft.SerializeReferenceExtensions.Editor
|
|||||||
|
|
||||||
static Type GetCustomPropertyDrawerType (Type type)
|
static Type GetCustomPropertyDrawerType (Type type)
|
||||||
{
|
{
|
||||||
|
Type[] interfaceTypes = type.GetInterfaces();
|
||||||
|
|
||||||
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
{
|
{
|
||||||
foreach (Type drawerType in assembly.GetTypes())
|
foreach (Type drawerType in assembly.GetTypes())
|
||||||
@@ -36,9 +38,39 @@ namespace MackySoft.SerializeReferenceExtensions.Editor
|
|||||||
if (field != null)
|
if (field != null)
|
||||||
{
|
{
|
||||||
var fieldType = field.GetValue(customPropertyDrawer) as Type;
|
var fieldType = field.GetValue(customPropertyDrawer) as Type;
|
||||||
if (fieldType != null && fieldType == type)
|
if (fieldType != null)
|
||||||
{
|
{
|
||||||
return drawerType;
|
if (fieldType == type)
|
||||||
|
{
|
||||||
|
return drawerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the property drawer also allows for being applied to child classes, check if they match
|
||||||
|
var useForChildrenField = customPropertyDrawer.GetType().GetField("m_UseForChildren", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
if (useForChildrenField != null)
|
||||||
|
{
|
||||||
|
object useForChildrenValue = useForChildrenField.GetValue(customPropertyDrawer);
|
||||||
|
if (useForChildrenValue is bool && (bool)useForChildrenValue)
|
||||||
|
{
|
||||||
|
// Check interfaces
|
||||||
|
if (Array.Exists(interfaceTypes, interfaceType => interfaceType == fieldType))
|
||||||
|
{
|
||||||
|
return drawerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check derived types
|
||||||
|
Type baseType = type.BaseType;
|
||||||
|
while (baseType != null)
|
||||||
|
{
|
||||||
|
if (baseType == fieldType)
|
||||||
|
{
|
||||||
|
return drawerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
baseType = baseType.BaseType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
#if UNITY_2019_3_OR_NEWER
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace MackySoft.SerializeReferenceExtensions.Editor
|
||||||
|
{
|
||||||
|
public static class SerializedPropertyExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<SerializedProperty> GetChildProperties (this SerializedProperty parent, int depth = 1)
|
||||||
|
{
|
||||||
|
parent = parent.Copy();
|
||||||
|
|
||||||
|
int depthOfParent = parent.depth;
|
||||||
|
var enumerator = parent.GetEnumerator();
|
||||||
|
|
||||||
|
while (enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
if (enumerator.Current is not SerializedProperty childProperty)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (childProperty.depth > (depthOfParent + depth))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
yield return childProperty.Copy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b934aeca38cb7a24cabd6047fe0e298a
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
+47
-23
@@ -31,49 +31,74 @@ namespace MackySoft.SerializeReferenceExtensions.Editor
|
|||||||
|
|
||||||
SerializedProperty m_TargetProperty;
|
SerializedProperty m_TargetProperty;
|
||||||
|
|
||||||
public override void OnGUI (Rect position,SerializedProperty property,GUIContent label) {
|
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
|
||||||
EditorGUI.BeginProperty(position,label,property);
|
{
|
||||||
|
EditorGUI.BeginProperty(position, label, property);
|
||||||
|
|
||||||
|
if (property.propertyType == SerializedPropertyType.ManagedReference)
|
||||||
|
{
|
||||||
|
// Render label first to avoid label overlap for lists
|
||||||
|
Rect foldoutLabelRect = new Rect(position);
|
||||||
|
foldoutLabelRect.height = EditorGUIUtility.singleLineHeight;
|
||||||
|
foldoutLabelRect = EditorGUI.IndentedRect(foldoutLabelRect);
|
||||||
|
Rect popupPosition = EditorGUI.PrefixLabel(foldoutLabelRect, label);
|
||||||
|
|
||||||
if (property.propertyType == SerializedPropertyType.ManagedReference) {
|
|
||||||
// Draw the subclass selector popup.
|
// Draw the subclass selector popup.
|
||||||
Rect popupPosition = new Rect(position);
|
if (EditorGUI.DropdownButton(popupPosition, GetTypeName(property), FocusType.Keyboard))
|
||||||
popupPosition.width -= EditorGUIUtility.labelWidth;
|
{
|
||||||
popupPosition.x += EditorGUIUtility.labelWidth;
|
|
||||||
popupPosition.height = EditorGUIUtility.singleLineHeight;
|
|
||||||
|
|
||||||
if (EditorGUI.DropdownButton(popupPosition,GetTypeName(property),FocusType.Keyboard)) {
|
|
||||||
TypePopupCache popup = GetTypePopup(property);
|
TypePopupCache popup = GetTypePopup(property);
|
||||||
m_TargetProperty = property;
|
m_TargetProperty = property;
|
||||||
popup.TypePopup.Show(popupPosition);
|
popup.TypePopup.Show(popupPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a custom property drawer exists for this type.
|
// Draw the foldout.
|
||||||
PropertyDrawer customDrawer = GetCustomPropertyDrawer(property);
|
if (!string.IsNullOrEmpty(property.managedReferenceFullTypename))
|
||||||
if (customDrawer != null)
|
|
||||||
{
|
{
|
||||||
// Draw the property with custom property drawer.
|
|
||||||
Rect foldoutRect = new Rect(position);
|
Rect foldoutRect = new Rect(position);
|
||||||
foldoutRect.height = EditorGUIUtility.singleLineHeight;
|
foldoutRect.height = EditorGUIUtility.singleLineHeight;
|
||||||
property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, label, true);
|
foldoutRect.x -= 12;
|
||||||
|
property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, GUIContent.none, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (property.isExpanded)
|
// Draw property if expanded.
|
||||||
|
if (property.isExpanded)
|
||||||
|
{
|
||||||
|
using (new EditorGUI.IndentLevelScope())
|
||||||
{
|
{
|
||||||
using (new EditorGUI.IndentLevelScope())
|
// Check if a custom property drawer exists for this type.
|
||||||
|
PropertyDrawer customDrawer = GetCustomPropertyDrawer(property);
|
||||||
|
if (customDrawer != null)
|
||||||
{
|
{
|
||||||
|
// Draw the property with custom property drawer.
|
||||||
Rect indentedRect = position;
|
Rect indentedRect = position;
|
||||||
float foldoutDifference = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
float foldoutDifference = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||||
indentedRect.height = customDrawer.GetPropertyHeight(property, label);
|
indentedRect.height = customDrawer.GetPropertyHeight(property, label);
|
||||||
indentedRect.y += foldoutDifference;
|
indentedRect.y += foldoutDifference;
|
||||||
customDrawer.OnGUI(indentedRect, property, label);
|
customDrawer.OnGUI(indentedRect, property, label);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Draw the properties of the child elements.
|
||||||
|
// NOTE: In the following code, since the foldout layout isn't working properly, I'll iterate through the properties of the child elements myself.
|
||||||
|
// EditorGUI.PropertyField(position, property, GUIContent.none, true);
|
||||||
|
|
||||||
|
Rect childPosition = position;
|
||||||
|
childPosition.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||||
|
foreach (SerializedProperty childProperty in property.GetChildProperties())
|
||||||
|
{
|
||||||
|
float height = EditorGUI.GetPropertyHeight(childProperty, new GUIContent(childProperty.displayName, childProperty.tooltip), true);
|
||||||
|
childPosition.height = height;
|
||||||
|
EditorGUI.PropertyField(childPosition, childProperty, true);
|
||||||
|
|
||||||
|
childPosition.y += height + EditorGUIUtility.standardVerticalSpacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
EditorGUI.PropertyField(position, property, label, true);
|
{
|
||||||
}
|
EditorGUI.LabelField(position, label, k_IsNotManagedReferenceLabel);
|
||||||
} else {
|
|
||||||
EditorGUI.LabelField(position,label,k_IsNotManagedReferenceLabel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorGUI.EndProperty();
|
EditorGUI.EndProperty();
|
||||||
@@ -115,7 +140,6 @@ namespace MackySoft.SerializeReferenceExtensions.Editor
|
|||||||
foreach (var targetObject in m_TargetProperty.serializedObject.targetObjects) {
|
foreach (var targetObject in m_TargetProperty.serializedObject.targetObjects) {
|
||||||
SerializedObject individualObject = new SerializedObject(targetObject);
|
SerializedObject individualObject = new SerializedObject(targetObject);
|
||||||
SerializedProperty individualProperty = individualObject.FindProperty(m_TargetProperty.propertyPath);
|
SerializedProperty individualProperty = individualObject.FindProperty(m_TargetProperty.propertyPath);
|
||||||
|
|
||||||
object obj = individualProperty.SetManagedReference(type);
|
object obj = individualProperty.SetManagedReference(type);
|
||||||
individualProperty.isExpanded = (obj != null);
|
individualProperty.isExpanded = (obj != null);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "com.mackysoft.serializereference-extensions",
|
"name": "com.mackysoft.serializereference-extensions",
|
||||||
"displayName": "SerializeReference Extensions",
|
"displayName": "SerializeReference Extensions",
|
||||||
"version": "1.1.9",
|
"author": { "name": "MackySoft", "url": "https://github.com/mackysoft" },
|
||||||
"unity": "2019.4",
|
"version": "1.3.0",
|
||||||
|
"unity": "2021.3",
|
||||||
"description": "Provide popup to specify the type of the field serialized by the [SerializeReference] attribute in the inspector.",
|
"description": "Provide popup to specify the type of the field serialized by the [SerializeReference] attribute in the inspector.",
|
||||||
"keywords": [ "SerializeReference", "Editor" ],
|
"keywords": [ "SerializeReference", "Editor" ],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -15,9 +15,18 @@ The `SubclassSelector` attribute allows you to easily set subclasses of those ab
|
|||||||
- Easily set subclass by popup.
|
- Easily set subclass by popup.
|
||||||
- **[New]** Type finding by fuzzy finder.
|
- **[New]** Type finding by fuzzy finder.
|
||||||
- **[New]** Override the type name and path by the `AddTypeMenu` attribute.
|
- **[New]** Override the type name and path by the `AddTypeMenu` attribute.
|
||||||
|
- **[New]** Available `CustomPropertyDrawer` for subclasses.
|
||||||
|
- **[New]** Restore values of previous object from JSON when subclass is changed. (required Unity 2021.3 or later)
|
||||||
|
- **[New]** Copy & Paste the subclass properties. (required Unity 2021.3 or later)
|
||||||
|
|
||||||
|
> See below for the reason for the limitation of versions less than Unity 2021.3.
|
||||||
|
>
|
||||||
|
> https://blog.unity.com/engine-platform/serializereference-improvements-in-unity-2021-lts
|
||||||
|
|
||||||
## 📥 Installation
|
## 📥 Installation
|
||||||
|
|
||||||
|
#### Install via `.unitypackage`
|
||||||
|
|
||||||
Download any version from releases.
|
Download any version from releases.
|
||||||
|
|
||||||
Releases: https://github.com/mackysoft/Unity-SerializeReferenceExtensions/releases
|
Releases: https://github.com/mackysoft/Unity-SerializeReferenceExtensions/releases
|
||||||
@@ -26,10 +35,17 @@ Releases: https://github.com/mackysoft/Unity-SerializeReferenceExtensions/releas
|
|||||||
|
|
||||||
Or, you can add this package by opening PackageManager and entering
|
Or, you can add this package by opening PackageManager and entering
|
||||||
|
|
||||||
`https://github.com/mackysoft/Unity-SerializeReferenceExtensions.git?path=Assets/MackySoft/MackySoft.SerializeReferenceExtensions`
|
```
|
||||||
|
https://github.com/mackysoft/Unity-SerializeReferenceExtensions.git?path=Assets/MackySoft/MackySoft.SerializeReferenceExtensions
|
||||||
|
```
|
||||||
|
|
||||||
from the `Add package from git URL` option.
|
from the `Add package from git URL` option.
|
||||||
|
|
||||||
|
If you are specifying a version, enter `#{VERSION}` at the end, as shown below.
|
||||||
|
|
||||||
|
```
|
||||||
|
https://github.com/mackysoft/Unity-SerializeReferenceExtensions.git?path=Assets/MackySoft/MackySoft.SerializeReferenceExtensions#1.1.9
|
||||||
|
```
|
||||||
|
|
||||||
#### Install via Open UPM
|
#### Install via Open UPM
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user