TylerTemp / SaintsField

A Unity Inspector extension tool focusing on script fields inspector enhancement
MIT License
154 stars 9 forks source link

arg out of range error #62

Open laurentopia opened 1 month ago

laurentopia commented 1 month ago

Hello, Just ran into this, might be nothing, it happens every now and then and I don't know what causes it, if you stumble on a solution...

ArgumentOutOfRangeException: Exception of type 'System.ArgumentOutOfRangeException' was thrown. Parameter name: getPropType Actual value was NotFound. SaintsField.Editor.Drawers.RequiredAttributeDrawer.Truly (UnityEditor.SerializedProperty property, System.Object target) (at Library/PackageCache/today.comes.saintsfield@86a6fefd86/Editor/Drawers/RequiredAttributeDrawer.cs:34) SaintsField.Editor.Drawers.RequiredAttributeDrawer.GetErrorImGui (UnityEditor.SerializedProperty property, SaintsField.ISaintsAttribute saintsAttribute, System.Reflection.FieldInfo info, System.Object parent) (at Library/PackageCache/today.comes.saintsfield@86a6fefd86/Editor/Drawers/RequiredAttributeDrawer.cs:86) SaintsField.Editor.Drawers.RequiredAttributeDrawer.GetBelowExtraHeight (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Single width, SaintsField.ISaintsAttribute saintsAttribute, System.Reflection.FieldInfo info, System.Object parent) (at Library/PackageCache/today.comes.saintsfield@86a6fefd86/Editor/Drawers/RequiredAttributeDrawer.cs:113) SaintsField.Editor.Core.SaintsPropertyDrawer+<>c__DisplayClass19_1.<GetPropertyHeight>b__9 (System.Collections.Generic.KeyValuePair2[TKey,TValue] each) (at Library/PackageCache/today.comes.saintsfield@86a6fefd86/Editor/Core/SaintsPropertyDrawer.cs:406) System.Linq.Enumerable+SelectIListIterator2[TSource,TResult].MoveNext () (at <351e49e2a5bf4fd6beabb458ce2255f3>:0) System.Linq.Enumerable+WhereEnumerableIterator1[TSource].MoveNext () (at <351e49e2a5bf4fd6beabb458ce2255f3>:0) System.Linq.Enumerable+DefaultIfEmptyIterator1[TSource].MoveNext () (at <351e49e2a5bf4fd6beabb458ce2255f3>:0) System.Linq.Enumerable.Sum (System.Collections.Generic.IEnumerable1[T] source) (at <351e49e2a5bf4fd6beabb458ce2255f3>:0) SaintsField.Editor.Core.SaintsPropertyDrawer.GetPropertyHeight (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at Library/PackageCache/today.comes.saintsfield@86a6fefd86/Editor/Core/SaintsPropertyDrawer.cs:413) UnityEditor.PropertyDrawer.GetPropertyHeightSafe (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at <25578071f6e44201aac745680e5c8dfc>:0) UnityEditor.PropertyHandler.GetHeight (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren) (at <25578071f6e44201aac745680e5c8dfc>:0) UnityEditor.PropertyHandler.OnGUILayout (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at <25578071f6e44201aac745680e5c8dfc>:0) UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, System.Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at <25578071f6e44201aac745680e5c8dfc>:0) UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, UnityEngine.GUILayoutOption[] options) (at <25578071f6e44201aac745680e5c8dfc>:0) SaintsField.Editor.Playa.Renderer.SerializedFieldRenderer.Render () (at Library/PackageCache/today.comes.saintsfield@86a6fefd86/Editor/Playa/Renderer/SerializedFieldRenderer.cs:546) SaintsField.Editor.SaintsEditor.OnInspectorGUI () (at Library/PackageCache/today.comes.saintsfield@86a6fefd86/Editor/SaintsEditor.cs:196) UnityEditor.UIElements.InspectorElement+<>c__DisplayClass59_0.b__0 () (at :0) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&) `

laurentopia commented 1 month ago

Ah now it's happening all the time. I think it has to do with this base class where isRelay used in [HideIf(nameOf(isRelay)] is getting overriden in a child class .... but it worked fine earlier

public class MCDamageHandler : MonoBehaviour
{
    [Expandable, Required]
    public MCTeam team;
    [SerializeField, HideIf(nameof(isRelay))]
    float _health = 100f;
    [HideIf(nameof(isRelay))]
    internal float _currentHealth;
    public virtual float Health           { get { return _currentHealth; } set { _currentHealth = value; } }
    public         float normalizedHealth => Health / _health;
    [GetComponent, HideIf(nameof(isRelay))]
    public Rigidbody rigidBody;
    [HideIf(nameof(isRelay))]
    public Transform targetOffset;
    public virtual void OnEnable() => Health = _currentHealth = _health;
    public bool IsHealthLessThan(float h) => _currentHealth < h;
    public bool IsHealth_PercentLessThan(float percent) => Health / _health * 100.0 < percent;
    public virtual bool isRelay => false;
}

public class MCUnitChild : MCDamageHandler
{
    public override bool isRelay => true;
    [GetComponentInParents]
    public MCUnit unit;
}
laurentopia commented 1 month ago

found it: image [required, expandable] on a field that's not set = bomb

laurentopia commented 1 month ago

nah it's [require] only bombing this which is quite off bc i've been using it a lot. maybe required bombs on scriptableobject? here's the SO bombing required when ref to it is null hope this helps hunting this nasty bug down

using System;
using System.Collections;
using System.Collections.Generic;
using SaintsField;
using SaintsField.Playa;
using UnityEngine;
using UnityEngine.Serialization;
using Vertx.Debugging;

// team system
// rule: if friend and gets put as enemy, first remove from friend list, as a chance before turning into enemy
public enum ALLIANCETYPE { FRIEND, NEUTRAL, ENEMY, SELF }
[CreateAssetMenu]
public class MCTeam : ScriptableObject
{
    [Tooltip("for physics raycast, <everything> is fine but setting it can help optimize")]
    public LayerMask layers;
    public List<TeamCounter> alliances;
    [MinMaxSlider(-10, 10)]
    public Vector2 neutralRange = new Vector2(-1, 1);
#if UNITY_EDITOR
    void OnValidate()
    {
        for (var i = alliances.Count - 1; i >= 0; i--) {
            var a = alliances[i];
            a.neutralRange = neutralRange;
            if (a.team == this) alliances.RemoveAt(i);
            if (alliances.FindAll(tt => tt.team == a.team).Count > 1) a.team = null;
        }
    }
#endif
    public ALLIANCETYPE GetAlliance(MCTeam t) => alliances.Find(a => a.team == t).alliance;

    public (ALLIANCETYPE, float) ChangeAlliance(MCTeam t, float delta)
    {
        if (t == this) return (ALLIANCETYPE.SELF, 0);
        TeamCounter teamCounter = alliances.Find(a => a.team == t);
        teamCounter.affinity += delta;
        return (teamCounter.alliance, teamCounter.affinity);
    }

    [Serializable]
    public class TeamCounter
    {
        [Layout("ream counter", ELayout.Horizontal)]
        [Required]
        public MCTeam team;
        [ProgressBar(-20, 20, step: 1f, colorCallback: nameof(FillColor))]
        public float affinity;
        public ALLIANCETYPE alliance
        {
            get {
                if (affinity > neutralRange.y) return ALLIANCETYPE.FRIEND;
                else if (affinity < neutralRange.x) return ALLIANCETYPE.ENEMY;
                else return ALLIANCETYPE.NEUTRAL;
            }
        }
        [HideInInspector]
        public Vector2 neutralRange;
    #if UNITY_EDITOR
        private EColor FillColor() => alliance == ALLIANCETYPE.ENEMY ? EColor.Red : (alliance == ALLIANCETYPE.FRIEND ? EColor.Green : EColor.Gray);
    #endif
    }
}
TylerTemp commented 1 month ago

This is because alliances.RemoveAt(i); will make the drawer disappear, but Unity will still draw once after it's gone.

I'll fix it in the drawer level.

TylerTemp commented 1 month ago

Hi, this bug has been fixed in dev branch, you can have a try. I'll push a new release later.

TylerTemp commented 1 month ago

Hi, please upgrade to 3.2.2 to see if it's fixed

laurentopia commented 1 month ago

nope still the same

ArgumentOutOfRangeException: Exception of type 'System.ArgumentOutOfRangeException' was thrown.
Parameter name: getPropType
Actual value was NotFound.
SaintsField.Editor.Drawers.RequiredAttributeDrawer.Truly (UnityEditor.SerializedProperty property, System.Object target) (at Library/PackageCache/today.comes.saintsfield@a016219fd0/Editor/Drawers/RequiredAttributeDrawer.cs:34)
SaintsField.Editor.Drawers.RequiredAttributeDrawer.GetErrorImGui (UnityEditor.SerializedProperty property, SaintsField.ISaintsAttribute saintsAttribute, System.Reflection.FieldInfo info, System.Object parent) (at Library/PackageCache/today.comes.saintsfield@a016219fd0/Editor/Drawers/RequiredAttributeDrawer.cs:86)
TylerTemp commented 1 month ago

After reading #60 you're on Unity 2020 which uses IMGUI instead of UI Toolkit.

I'll patch IMGUI and release the fix soon

TylerTemp commented 1 month ago

Hi, please check if it's been fixed in 3.2.3

laurentopia commented 1 month ago

congrats!

laurentopia commented 1 month ago

oops, spoke to fast image

TylerTemp commented 1 month ago

Hi, before I digging into it: can you check if the error message came from RequiredAttributeDrawer (Or simply comment out [Required] from the parent).

In this version the Required can not work in a parent class, and has been fixed in dev branch which I'll release the fix later.

If not, please give a more specific Unity version number and I'll try re-produce it later today

laurentopia commented 1 month ago

Hi, before I digging into it: can you check if the error message came from RequiredAttributeDrawer (Or simply comment out [Required] from the parent).

that's the one, yes. removing [Required] fixes the issue.

TylerTemp commented 1 month ago

Hi, before I digging into it: can you check if the error message came from RequiredAttributeDrawer (Or simply comment out [Required] from the parent).

that's the one, yes. removing [Required] fixes the issue.

3.2.4 has Required fixed. Please have a look