Code Monkey home page Code Monkey logo

alchemy's Introduction

Stats

stats-dark stats-light

alchemy's People

Contributors

akeit0 avatar annulusgames avatar aprius avatar arktarusov avatar moz-moz avatar pjbarczyk avatar yusuke57 avatar yuyu0127 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

alchemy's Issues

InternalAPIHelper does not work on Unity 2023.3 or later

Due to a change in the argument of the internal API GetDrawerTypeForType, Alchemy causes an error when building the Inspector in Unity 2023.3 and later versions. We need to isolate the process with #if and pass the appropriate arguments with reflection.

Nested Lists of Lists of Lists are leading to NullReferenceException when pressing "+" in the Inspector

Hey,

first of all - we love Alchemy and this is our first issue we're encountering. So we wanted to report it, to see if anyone has a fix already.

Unity Version: 2022.3.17f1
Alchemy Version: 2.0.1

Example reproduction code file:

using System.Collections;
using System.Collections.Generic;
using Alchemy.Inspector;
using UnityEngine;

[Serializable]
public class ContainerClass
{
    [SerializeField] public List<int> listOfInt = new List<int>();

}

[Serializable]
public class SecondContainerClass
{
    [SerializeField] public List<ContainerClass> listOfContainerClass = new List<ContainerClass>();

}


public class MyTest : MonoBehaviour
{
    [SerializeField] public List<SecondContainerClass> listOfListOfList = new List<SecondContainerClass>();

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }
}

Simply add this to any GameObject and press plus in the nested lists:

image

Error in screenshot:
image

Error as text:

NullReferenceException: Object reference not set to an instance of an object
Alchemy.Editor.Elements.PropertyListView+<>c__DisplayClass0_2.<.ctor>b__2 (UnityEditor.SerializedProperty x) (at ./Library/PackageCache/com.annulusgames.alchemy@b03898d42a/Editor/Elements/PropertyListView.cs:32)
UnityEditor.UIElements.Bindings.DefaultSerializedObjectBindingImplementation+<>c__DisplayClass7_0.<TrackPropertyValue>b__0 (System.Object e, UnityEditor.SerializedProperty p) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:1010)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.UpdateTrackedProperties () (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:844)
UnityEditor.RetainedMode:UpdateSchedulers() (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/RetainedMode.cs:55)

Thanks for your time looking at this and if you got any input or ideas, let us know :)

Button Attribute in struct doesn't work well.

Because the struct is boxed, the changes are not reflected when using a Button Attribute.

[Serializable]
public struct MyStruct 
{
    public int Value;
    
    [Button]
    public void Fuga()
    {
       // Can not get latest value.
        Debug.Log(Value);
       //Can not set new value.
       Value=0;
    }
}

Changes in PropertyListView are not reflected when field don't have OnListViewChangedAttribute.

public sealed class PropertyListView : BindableElement
{
    public PropertyListView(SerializedProperty property, int depth)
    {
        Assert.IsTrue(property.isArray);

        var parentObj = property.GetDeclaredObject();
        var events = property.GetAttribute<OnListViewChangedAttribute>(true);

        var listView = GUIHelper.CreateListViewFromFieldInfo(parentObj, property.GetFieldInfo());
        listView.headerTitle = ObjectNames.NicifyVariableName(property.displayName);
        listView.bindItem = (element, index) =>
        {
            var arrayElement = property.GetArrayElementAtIndex(index);
            var e = new AlchemyPropertyField(arrayElement, property.GetPropertyType(true), depth + 1, true);
            element.Add(e);
            element.Bind(arrayElement.serializedObject);
    //if(events!=null) you seems to forget to add this line. 
            e.TrackPropertyValue(arrayElement, x =>
            {
                ReflectionHelper.Invoke(parentObj, events.OnItemChanged, new object[] { index, x.GetValue<object>() });
            });
        };

Request for adding `Scene` attribute

Hi! Are you planning to add attribute to choose scene in inspector from dropdown?
like:

[SerializeField, Scene] private string gameSceneName;

and in inspector it might look like:
image

or it might be a new styled dropdown with a searchbar

thanks in advance!

Buttons with the same name function do not appear.

Related to #15
Following will solve this problem.

 static IEnumerable<MemberInfo> GetMembersIncludingBaseNonPublic(Type type, BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
{
-  return EnumerateTypeHierarchy(type).Reverse().SelectMany(t => t.GetMembers(bindingAttr)).Distinct(MemberInfoEqualityComparer.Instance);
+  return EnumerateTypeHierarchy(type).Reverse().SelectMany(t => t.GetMembers(bindingAttr|BindingFlags.DeclaredOnly));
}

TabGroups don't indent arrays, lists etc properly.

image
image

List (and array, and dictionary etc) foldouts don't get indented properly inside TabGroups. Had a quick look into it, but I'm not good with the UIElements stuff so couldn't figure it out.
Lists with foldouts inside FoldoutGroups do indent correctly.

Test case here:

using UnityEngine;
using Alchemy.Inspector;

public class Oops : MonoBehaviour
{
	[SerializeField] string[] goodStrings = { "foo", "bar" };
	[SerializeField, TabGroup("Bad Zone")] string[] badStrings = { "boo", "far" };
	[SerializeField, TabGroup("Another Tab"), ListViewSettings(ShowFoldoutHeader = false)] string[] fineStrings = { "fixed without the foldout via ListViewSettings", "goo", "tar" };
	[SerializeField, FoldoutGroup("Foldouts are okay")] string[] goodStrings2 = { "foo", "bar" };
}

Unity 2022.3.23f1 Inspectorでインターフェースクラスがエラーで表示されない問題

Unityのバージョンを2024/04/05にReleaseされた Unity 2022.3.23f1 にアップデートしたところ、
以下のエラーがコンソールに表示され、Inspectorにインターフェースクラスなどが表示できない問題が発生しております。
おそらく、ReleaseNoteを見る限りBuild Systemになにか変更が入ったようなので、そちらが原因かもしれません。

お手数ですが、対応などを検討していただければ幸いです。

TargetParameterCountException: Number of parameters specified does not match the expected number.
System.Reflection.RuntimeMethodInfo.ConvertValues (System.Reflection.Binder binder, System.Object[] args, System.Reflection.ParameterInfo[] pinfo, System.Globalization.CultureInfo culture, System.Reflection.BindingFlags invokeAttr) (at <b11ba2a8fbf24f219f7cc98532a11304>:0)
System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <b11ba2a8fbf24f219f7cc98532a11304>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <b11ba2a8fbf24f219f7cc98532a11304>:0)
Alchemy.Editor.InternalAPIHelper.GetDrawerTypeForType (System.Type classType) (at ./Library/PackageCache/com.annulusgames.alchemy@d874e72f18/Editor/Internal/InternalAPIHelper.cs:29)
Alchemy.Editor.InspectorHelper.BuildElements (UnityEditor.SerializedObject serializedObject, UnityEngine.UIElements.VisualElement rootElement, System.Object target, System.Func`2[T,TResult] findPropertyFunc, System.Int32 depth) (at ./Library/PackageCache/com.annulusgames.alchemy@d874e72f18/Editor/Internal/InspectorHelper.cs:126)
Alchemy.Editor.AlchemyEditor.CreateInspectorGUI () (at ./Library/PackageCache/com.annulusgames.alchemy@d874e72f18/Editor/AlchemyEditor.cs:95)
UnityEditor.UIElements.InspectorElement.CreateInspectorElementUsingUIToolkit (UnityEditor.Editor targetEditor) (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.UIElements.InspectorElement.CreateInspectorElementFromSerializedObject (UnityEditor.SerializedObject bindObject) (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.UIElements.InspectorElement.ExecuteDefaultActionAtTarget (UnityEngine.UIElements.EventBase evt) (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEngine.UIElements.CallbackEventHandler.HandleEvent (UnityEngine.UIElements.EventBase evt) (at <79a7b2c7005043d7ba49637ce6eae1bd>:0)
UnityEngine.UIElements.CallbackEventHandler.HandleEventAtCurrentTargetAndPhase (UnityEngine.UIElements.EventBase evt) (at <79a7b2c7005043d7ba49637ce6eae1bd>:0)
UnityEngine.UIElements.CallbackEventHandler.HandleEventAtTargetPhase (UnityEngine.UIElements.EventBase evt) (at <79a7b2c7005043d7ba49637ce6eae1bd>:0)
UnityEngine.UIElements.CallbackEventHandler.HandleEventAtTargetAndDefaultPhase (UnityEngine.UIElements.EventBase evt) (at <79a7b2c7005043d7ba49637ce6eae1bd>:0)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.SendBindingEvent[TEventType] (TEventType evt, UnityEngine.UIElements.VisualElement target) (at <70d92763e0394a19a8eb6aa7c1a65449>:0)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.BindTree (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at <70d92763e0394a19a8eb6aa7c1a65449>:0)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.ContinueBinding (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at <70d92763e0394a19a8eb6aa7c1a65449>:0)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.Bind (UnityEngine.UIElements.VisualElement element) (at <70d92763e0394a19a8eb6aa7c1a65449>:0)
UnityEditor.UIElements.Bindings.DefaultSerializedObjectBindingImplementation.Bind (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedObject obj) (at <70d92763e0394a19a8eb6aa7c1a65449>:0)
UnityEditor.UIElements.BindingExtensions.Bind (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedObject obj) (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.SerializedObject obj, UnityEditor.Editor editor, UnityEditor.UIElements.InspectorElement+DefaultInspectorFramework defaultInspectorFramework) (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.Editor editor, UnityEditor.UIElements.InspectorElement+DefaultInspectorFramework defaultInspectorFramework) (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.Editor editor) (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.UIElements.EditorElement.BuildInspectorElement () (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.UIElements.EditorElement.CreateInspectorElement () (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.EditorElementUpdater.CreateInspectorElementsForViewport (UnityEngine.UIElements.ScrollView viewport, UnityEngine.UIElements.VisualElement contentContainer) (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.PropertyEditor.RebuildContentsContainers () (at <1899c5bd2a6d466081cd705bee01d689>:0)
UnityEditor.InspectorWindow.RedrawFromNative () (at <1899c5bd2a6d466081cd705bee01d689>:0)

Reflectionにおける継承の扱いについて

ReflectionHelperにおける継承の扱いなんですが、bool inheritで継承元まで探すか決めているところが多くありますが、
interfaceでなければ、BindingFlags.DeclaredOnlyを付けない限り、継承元まで探すはずです。

なので、GetAllPropertiesIncludingInheritedのような場所や、見つからなければ継承元で繰り返すような処理は必要なく、
逆に継承元まで探さないはずなのに、探すという状態になってしまっています。

以下は個人的リファクタリングの提案ですが、

FieldInfo info;
if (cacheFieldInfo.ContainsKey((type, name, bindingAttr, inherit)))
{
  info = cacheFieldInfo[(type, name, bindingAttr, inherit)];
}
else

などは、やはり

FieldInfo info;
if (!cacheFieldInfo.TryGetValue((type, name, bindingAttr, inherit), out info))
{

にしてほしいなという前にも別のところでした提案です。(書き方が好きじゃないとかであればいいですが)
あとSerializationHelperで
if (IsUnityObject<T>)

if (target is UnityEngine.Object targetUnityObject)にするとのちの as castもいらず、いいかなと思います

FoldOut in a Group is overflowing.

スクリーンショット 2024-02-17 174621
To solve this, increase padding or query with Foldout type.

helpBox.schedule.Execute(() =>
{
    foreach (var foldout in  helpBox.Query<Foldout>().Build())
    {
        if(foldout.parent == helpBox || foldout.parent.parent == helpBox)
            foldout.style.left = 12f;
    }
});

スクリーンショット 2024-02-17 180641

要件を満たすUnityバージョンでコンパイルエラーが発生する

概要

要件
Unity 2021.2 以上 (シリアル化拡張を使用する場合、2022.1以上を推奨)
Serialization 2.0 以上 (シリアル化拡張を使用する場合)

こちらの「要件」を満たす環境でコンパイルエラーが発生し、動作しないことを確認しました。

環境

  • Alchemy:2.0.1(Package Manager 経由で導入)
  • Unity:2021.3.25f1
  • OS:macOS Ventura 13.6.4

エラー内容

下記5箇所のUIElementsに関するエラーが発生します。

  • Library/PackageCache/com.annulusgames.alchemy@e21ac9e231/Editor/Elements/GenericField.cs(105,30): error CS0246: The type or namespace name 'UnsignedIntegerField' could not be found (are you missing a using directive or an assembly reference?)
  • Library/PackageCache/com.annulusgames.alchemy@e21ac9e231/Editor/Elements/GenericField.cs(113,30): error CS0246: The type or namespace name 'UnsignedLongField' could not be found (are you missing a using directive or an assembly reference?)
  • Library/PackageCache/com.annulusgames.alchemy@e21ac9e231/Editor/Internal/GUIHelper.cs(85,26): error CS1061: 'ListView' does not contain a definition for 'itemsChosen' and no accessible extension method 'itemsChosen' accepting a first argument of type 'ListView' could be found (are you missing a using directive or an assembly reference?)
  • Library/PackageCache/com.annulusgames.alchemy@e21ac9e231/Editor/Internal/GUIHelper.cs(95,26): error CS1061: 'ListView' does not contain a definition for 'selectionChanged' and no accessible extension method 'selectionChanged' accepting a first argument of type 'ListView' could be found (are you missing a using directive or an assembly reference?)
  • Library/PackageCache/com.annulusgames.alchemy@e21ac9e231/Editor/Internal/GUIHelper.cs(100,26): error CS1061: 'ListView' does not contain a definition for 'selectedIndicesChanged' and no accessible extension method 'selectedIndicesChanged' accepting a first argument of type 'ListView' could be found (are you missing a using directive or an assembly reference?)

Fields hiding the inherited members of `Component` are displayed multiple times

Summary

Serialization of fields that hide the inherited members of Component (e.g. rigidbody, camera, collider) causes the fields to be displayed five times in the inspector.

  • It does not matter whether the field is serialized by having SerializeFieldAttribute or public access modifier.
  • Out of the five fields, the appropriate field is displayed as the second one.
  • When multiple issue-causing fields are present, the fields are grouped with each other, creating five groups of fields. Fields that behave correctly are displayed in the second group.
  • Type of the field does not matter; it can be the same, derive other UnityEngine.Object or be a primitive type.
  • The duplicated fields have the same property path, and so they are synchronized when the value is changed.
  • The issue does not occur when serializing auto-properties using the SerializeFieldAttribute for the backing field - the field is displayed only once.

Reproduction

In a newly created project, add the Alchemy 1.0.3 package. Then, create a new script with the following contents:

public class ExampleBehaviour : MonoBehaviour
{
    [SerializeField] private new Rigidbody rigidbody;
    [field: SerializeField] public Transform camera { get; private set; }
    public float light;
}

After adding this script to a game object, the inspector will look like this:

Inspector window

Note that the icons of the extraneous fields lack the icon and concrete component name. After changing the selection and reselecting the behaviour again, the icons and appropriate names appear.

Environment

The issue was found and reproduced in the following environment:

  • Unity 2023.1.16f1 and 2023.2.3f1
  • Alchemy 1.0.3

Hard to click the prefab button in Hierarchy

Hard to click the "open prefab" button in Hierarchy. The button is covered by toggles and component icons. It would be great to move a little bit left.

image
with Alchemy

image
the original

It is Unity 2023.2.11

Inspector element order is unpredictable with PropertyGroups

Expanded test case below. Turning methods into buttons does not always place them last in the inspector.

image

I did some quick experiments, and inverting the order in OrderByAttributeThenByMemberType() does make the buttons show up first even when group attributes are involved.

using UnityEngine;
using Alchemy.Inspector;

public class Oops : MonoBehaviour
{
	[SerializeField] string[] goodStrings = { "foo", "bar" };
	[SerializeField, TabGroup("Bad Zone")] string[] badStrings = { "boo", "far" };
	[SerializeField, TabGroup("Another Tab"), ListViewSettings(ShowFoldoutHeader = false)] string[] fineStrings = { "fixed by removing the foldout with ListViewSettings", "goo", "tar" };
	[SerializeField, FoldoutGroup("Foldouts are okay")] string[] goodStrings2 = { "foo", "bar" };
	[SerializeField] string test;

	[Button]
	void reticulateSplines() {
		Debug.Log("Reticulating splines...");
	}

	[Button(useParameters: false)]
	void PerformAction(string paramToIgnore, int number = 100) {
		Debug.Log($"Count: {number}");
	}

	[Button]
	void MoreMethod(int numberOfFoos = 50) {

		Debug.Log($"FooAmount: {numberOfFoos}");
	}
}

List field not working in Scriptable Objects with Alchemy enabled

Hey, I will really like to use this Editor Extension as it allows me to use [Button] attribute with parameters on methods, but I'm having the following issue with Lists:

To reproduce:

using UnityEngine;
using Alchemy.Inspector;
using System.Collections.Generic;

namespace CookingMarness
	{
		[CreateAssetMenu(fileName = "Test", menuName = "ScriptableObjects/Test")]
		public class TestSO : ScriptableObject
		{
			public List<int> Test = new List<int>();

			private void Reset()
			{
				Test?.Clear();
			}

			[Button]
			public void Add()
			{
				Test.Add(1);
			}
			[Button]
			public void Remove()
			{
				Test.Remove(1);
			}
		}
	}
}

It can get that behaviour:
image

And also if you remove elements from the list, thows errors arise:
image

Request to apply attributes on list field to each individual element

I've encountered an issue where attributes applied to list fields do not work as expected for each element within the lists. Specifically, attributes like [Required] and [AssetsOnly] seem to have no effect on the elements of the lists.

Example Code

[Required] // This attribute does not work as expected
public List<Object> requiredList;

[AssetsOnly] // This attribute does not work as expected
public List<Object> assetsOnlyList;

Expected Behavior

I expect the [Required] attribute to ensure that each element within the list is not null. Similarly, the [AssetsOnly] attribute should validate that each list element refers to an asset only.

Actual Behavior

The attributes seem to only apply to the list field itself and do not enforce the expected constraints on the individual elements within the list.

Request

I request a feature enhancement that allows these attributes to be applied effectively to each element within a list, ensuring that each element adheres to the specified constraints.

Note

Odin Inspector seems to use a [DontApplyToListElements] attribute to indicate that an attribute should be applied to the list itself, not to each element within the list.

Gradient、AnimationCurve対応

なんどもすみません。
GradientやAnimationCurve対応がUnity.Serializationでは今のところできないので、Adapter対応をお願いします。

NullReferenceException when inspecting derived class with private array-like field from base class

Issue Description

I am encountering a NullReferenceException when attempting to inspect a derived class that includes a private array or list field from its base class in the Inspector. This issue occurs under specific circumstances described below.

Exception

NullReferenceException: Object reference not set to an instance of an object
Alchemy.Editor.SerializedPropertyExtensions.GetPropertyType (UnityEditor.SerializedProperty property, System.Boolean isCollectionType) (at Assets/Alchemy/Editor/Internal/SerializedPropertyExtensions.cs:122)
Alchemy.Editor.Elements.AlchemyPropertyField..ctor (UnityEditor.SerializedProperty property, System.Type type, System.Boolean isArrayElement) (at Assets/Alchemy/Editor/Elements/AlchemyPropertyField.cs:34)
Alchemy.Editor.InspectorHelper.CreateMemberElement (UnityEditor.SerializedObject serializedObject, System.Object target, System.Reflection.MemberInfo memberInfo, System.Func`2[T,TResult] findPropertyFunc) (at Assets/Alchemy/Editor/Internal/InspectorHelper.cs:222)
Alchemy.Editor.InspectorHelper.BuildElements (UnityEditor.SerializedObject serializedObject, UnityEngine.UIElements.VisualElement rootElement, System.Object target, System.Func`2[T,TResult] findPropertyFunc) (at Assets/Alchemy/Editor/Internal/InspectorHelper.cs:133)
Alchemy.Editor.Elements.AlchemyPropertyField..ctor (UnityEditor.SerializedProperty property, System.Type type, System.Boolean isArrayElement) (at Assets/Alchemy/Editor/Elements/AlchemyPropertyField.cs:59)
Alchemy.Editor.InspectorHelper.CreateMemberElement (UnityEditor.SerializedObject serializedObject, System.Object target, System.Reflection.MemberInfo memberInfo, System.Func`2[T,TResult] findPropertyFunc) (at Assets/Alchemy/Editor/Internal/InspectorHelper.cs:222)
Alchemy.Editor.InspectorHelper.BuildElements (UnityEditor.SerializedObject serializedObject, UnityEngine.UIElements.VisualElement rootElement, System.Object target, System.Func`2[T,TResult] findPropertyFunc) (at Assets/Alchemy/Editor/Internal/InspectorHelper.cs:133)
Alchemy.Editor.AlchemyEditor.CreateInspectorGUI () (at Assets/Alchemy/Editor/AlchemyEditor.cs:95)
UnityEditor.UIElements.InspectorElement.CreateInspectorElementUsingUIToolkit (UnityEditor.Editor targetEditor) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:562)
UnityEditor.UIElements.InspectorElement.CreateInspectorElementFromSerializedObject (UnityEditor.SerializedObject bindObject) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:465)
UnityEditor.UIElements.InspectorElement.ExecuteDefaultActionAtTarget (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:374)
UnityEngine.UIElements.CallbackEventHandler.HandleEvent (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:281)
UnityEngine.UIElements.CallbackEventHandler.HandleEventAtCurrentTargetAndPhase (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:189)
UnityEngine.UIElements.CallbackEventHandler.HandleEventAtTargetPhase (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:175)
UnityEngine.UIElements.CallbackEventHandler.HandleEventAtTargetAndDefaultPhase (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:180)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.SendBindingEvent[TEventType] (TEventType evt, UnityEngine.UIElements.VisualElement target) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:85)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.BindTree (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:95)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.ContinueBinding (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:40)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.Bind (UnityEngine.UIElements.VisualElement element) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:31)
UnityEditor.UIElements.Bindings.DefaultSerializedObjectBindingImplementation.Bind (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedObject obj) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:816)
UnityEditor.UIElements.BindingExtensions.Bind (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedObject obj) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Bindings/BindingsInterface.cs:56)
UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.SerializedObject obj, UnityEditor.Editor editor, UnityEditor.UIElements.InspectorElement+DefaultInspectorFramework defaultInspectorFramework) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:317)
UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.Editor editor, UnityEditor.UIElements.InspectorElement+DefaultInspectorFramework defaultInspectorFramework) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:269)
UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.Editor editor) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:265)
UnityEditor.UIElements.EditorElement.BuildInspectorElement () (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/EditorElement.cs:171)
UnityEditor.UIElements.EditorElement.CreateInspectorElement () (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/EditorElement.cs:286)
UnityEditor.EditorElementUpdater.CreateInspectorElementsForViewport (UnityEngine.UIElements.ScrollView viewport, UnityEngine.UIElements.VisualElement contentContainer) (at /Users/bokken/build/output/unity/unity/Editor/Mono/Inspector/EditorElementUpdater.cs:99)
UnityEditor.PropertyEditor.RebuildContentsContainers () (at /Users/bokken/build/output/unity/unity/Editor/Mono/Inspector/PropertyEditor.cs:1115)
UnityEditor.PropertyEditor.OnGUI () (at /Users/bokken/build/output/unity/unity/Editor/Mono/Inspector/PropertyEditor.cs:420)
UnityEditor.HostView.InvokeOnGUI (UnityEngine.Rect onGUIPosition) (at /Users/bokken/build/output/unity/unity/Editor/Mono/HostView.cs:512)
UnityEditor.DockArea.DrawView (UnityEngine.Rect dockAreaRect) (at /Users/bokken/build/output/unity/unity/Editor/Mono/GUI/DockArea.cs:385)
UnityEditor.DockArea.OldOnGUI () (at /Users/bokken/build/output/unity/unity/Editor/Mono/GUI/DockArea.cs:376)
UnityEngine.UIElements.IMGUIContainer.DoOnGUI (UnityEngine.Event evt, UnityEngine.Matrix4x4 parentTransform, UnityEngine.Rect clippingRect, System.Boolean isComputingLayout, UnityEngine.Rect layoutSize, System.Action onGUIHandler, System.Boolean canAffectFocus) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/IMGUIContainer.cs:355)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:190)

Steps to Reproduce

  1. Define a serializable base class with a private array or list field.
  2. Create a serializable derived class that inherits from this base class.
  3. Attempt to inspect a component with a field of the derived class in the Inspector.

Sample Code

using UnityEngine;

namespace Alchemy.Samples
{
    public class InheritSample : MonoBehaviour
    {
        public DerivedClass derivedClass;

        [System.Serializable]
        public class BaseClass
        {
            [SerializeField]
            private float[] privateArray;
        }

        [System.Serializable]
        public class DerivedClass : BaseClass
        {
        }
    }
}

iOSビルドにてエラーが発生しました

version 1.0.0を使っています。
Unityは2022.3.13f1です。

iOS向けにビルドを行うとエラーが発生しました。
[Button]を使ってインスペクターにボタンを追加しています。

Library/PackageCache/com.annulusgames.alchemy@9dd5d44f0a/Runtime/Inspector/InspectorAttributes.cs(138,21): error CS0103: The name 'EditorGUIUtility' does not exist in the current context

SerializeをUnity.Serializationなしに汎用的にする提案

SourceGeneratorは大変になりますが、
以下のような代理表現を使えば、高速で使えるものになると思います。
時間があればお願いします。(私の方でForkして書くかも)

public interface IProxy<T> {
    public void ReadFrom(ref T target);
    public void WriteTo(ref T target);
}
[Serializable]
public struct ValueTupleSerializableProxy<T1,T2>:IProxy<ValueTuple<T1,T2>> {
    public T1 Item1;
    public T2 Item2;
    public void ReadFrom(ref ValueTuple<T1,T2> target) {
        Item1 = target.Item1;
        Item2 = target.Item2;
        ref var a = ref target.Item1;
    }
    public void WriteTo(ref ValueTuple<T1,T2> target) {
        target.Item1=Item1;
        target.Item2=Item2;
    }
}
[Serializable]
public struct CollectionSerializableProxy<TCollection,TElement,TProxyElement> : IProxy<TCollection> where TCollection : ICollection<TElement> where TProxyElement:struct ,IProxy<TElement> {
    public List<TProxyElement> Data;
    public void ReadFrom(ref TCollection target) {
        Data??=new List<TProxyElement>();
        Data.Clear();
        foreach (var element in target) {
            TProxyElement proxyElement = default;
            var element1 = element;
            proxyElement.ReadFrom(ref element1);
            Data.Add(proxyElement);
        }
    }
    public void WriteTo(ref TCollection target) {
        target??=Activator.CreateInstance<TCollection>();
        target.Clear();
        foreach (var proxyElement in Data) {
            var element = default(TElement);
            proxyElement.WriteTo(ref element);
            target.Add(element);
        }
    }
}

Non-private members and methods create multiple fields/buttons in derived classes' inspectors

When a script derives from another MonoBehaviour script, all non-private members and methods (public or protected with SerializeFieldAttribute) create extra fields or buttons.

Example

Create the following scripts in your project and add them to a GameObject:

// file: A.cs
public class A : MonoBehaviour
{
    public int aPublic;
    [SerializeField] protected int aProtected;
    [SerializeField] private int aPrivate;

    [Button] public void TestA() => Debug.Log($"Test from {nameof(A)}");
}

// file: B.cs
public class B : A
{
    public string bPublic;
    [SerializeField] protected string bProtected;
    [SerializeField] private string bPrivate;

    [Button] public void TestB() => Debug.Log($"Test from {nameof(B)}");
}

// file: C.cs
public class C : B
{
    public int cPublic;
    [SerializeField] protected int cProtected;
    [SerializeField] private int cPrivate;

    [Button] public void TestC() => Debug.Log($"Test from {nameof(C)}");
}

The inspector will look like this:

C Inspector

Related issues

The seems related to #12, though it covers an issue happening with private members too.

[InlineEditor] doesn't work for arrays

Regarding the behavior of InlineEditor attribute for UnityEngine.Object type array.

Expected behavior

InlineEditor is applied to each element of the array

Current behavior

InlineEditor doesn't work and isn't even serialized.

Reproduction code

using UnityEngine;
using Alchemy.Inspector;

public class SomeBehaviour : MonoBehaviour
{
     [SerializeField, InlineEditor] SomeScriptableObject[] objects;
}

Add automated tests for PR

Checking for PRs with remaining bugs will be automated with Github Actions. To do this, in addition to building a Github Actions workflow, we need to add some tests for Test Runner.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.