SaintsField icon indicating copy to clipboard operation
SaintsField copied to clipboard

Expandable doesn't update the SO value when nested in Unity 2020

Open laurentopia opened this issue 1 year ago • 17 comments

with this setup changing expanded team within the editor doesn't update the SO and colored progressbars don't follow color coding set by FillColor(): image image

[Expandable, Required]
public MCTeam team;

and that

public enum ALIANCETYPE { FRIEND, NEUTRAL, ENEMY }
[CreateAssetMenu]
public class MCTeam : ScriptableObject
{
	[Tooltip("for physics raycast, <everything> is fine but setting it can help optimize")]
	public LayerMask layers;
	public List<TeamCounter> aliances;
	[MinMaxSlider(-10, 10)]
	public Vector2 neutralRange = new Vector2(-1, 1);
#if UNITY_EDITOR
	void OnValidate()
	{
		for (var i = aliances.Count - 1; i >= 0; i--) {
			var a = aliances[i];
			a.neutralRange = neutralRange;
			if (a.team == this) aliances.RemoveAt(i);
			if (aliances.FindAll(tt => tt.team == a.team).Count > 1) a.team = null;
		}
	}
#endif
	public ALIANCETYPE GetAliance(MCTeam t) => aliances.Find(a => a.team == t).aliance;

	public ALIANCETYPE AddliancePoints(MCTeam t, int points)
	{
		TeamCounter teamCounter = aliances.Find(a => a.team == t);
		teamCounter.affinity += points;
		return teamCounter.aliance;
	}

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

laurentopia avatar Jul 24 '24 01:07 laurentopia

but changing neutralrange gets stores in the SO, perhaps it's failing within a list

laurentopia avatar Jul 24 '24 01:07 laurentopia

and i'm thinking, maybe it's conflicting with the drag and drop reordering of the list... yeah when dragging the progressbar the list element gets dragged, this is the wrong behavior as it contrasts with dragging the reference field which doesn't drag the element.

laurentopia avatar Jul 24 '24 01:07 laurentopia

confirmation that it also happens at runtime: that's the SO asset before event image after event image that's the thing referencing the SO after event image the color changed but not the value I had to select the SO then back the user to get value change. and these are the values all changing at the same time. image and that is also happening on the SO so my guess is we're seeing 2 bugs:

  1. ref of SO with expandable that contains a list don't update properly
  2. list of class containing progressbar update funky

laurentopia avatar Jul 24 '24 22:07 laurentopia

oops attached the wrong thing, this is all the sliders changing at the same time (list of class with progressbar in it) https://github.com/user-attachments/assets/9996d277-7461-4099-a2c1-15701fc31a2e

laurentopia avatar Jul 24 '24 22:07 laurentopia

There is some weird issue with struct + progressbar. Im looking into it

TylerTemp avatar Jul 25 '24 02:07 TylerTemp

Hi, please try this script if it's a bit better. (not actually solves everything but should make it more aligned with serialized data)

#if UNITY_EDITOR
using UnityEditor;
#endif

#if UNITY_EDITOR
void OnValidate()
{
    for (var i = aliances.Count - 1; i >= 0; i--)
    {
        var a = aliances[i];
        a.neutralRange = neutralRange;
        if (a.team == this)
        {
            Undo.RecordObject(this, name);  // add this
            aliances.RemoveAt(i);
        }
        if (aliances.FindAll(tt => tt.team == a.team).Count > 1)
        {
            Undo.RecordObject(this, name);  // add this
            a.team = null;
        }
    }
}
#endif

TylerTemp avatar Jul 25 '24 03:07 TylerTemp

Thanks, still doesn't work. I even boxed the onvalidate code in Application.isPlayer==false and removed it altogether. Could it be a 2020 special?

laurentopia avatar Jul 25 '24 23:07 laurentopia

Can you give Unity's full version (2020.x.f1 etc) so I can try re-produce it?

TylerTemp avatar Jul 26 '24 10:07 TylerTemp

OK I managed to re-produce it in 2020.1.0f1. It's a IMGUI issue. I'm looking into it

TylerTemp avatar Jul 27 '24 04:07 TylerTemp

https://github.com/user-attachments/assets/886c36ee-42ff-465b-8d7f-ad3db9cc35c9

Fixed. The fix will be released soon

TylerTemp avatar Jul 27 '24 04:07 TylerTemp

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

TylerTemp avatar Jul 27 '24 06:07 TylerTemp

image even with the onvalidate removed. edit and play time

laurentopia avatar Jul 29 '24 17:07 laurentopia

Hi, to be clear, does the issue now is:

  1. Now, the ProgressBar can be dragged independently
  2. The ProgressBar works fine in the ScriptableObject itself
  3. But in Expandable, the ProgressBar does not change color correctly, and the value is lost after editing in Expandable

TylerTemp avatar Jul 30 '24 07:07 TylerTemp

3.2.4 now will apply the changed value by Expandable in IMGUI, please have a try

TylerTemp avatar Jul 30 '24 08:07 TylerTemp

Almost there: it works fine from the [Expandable] scriptableobject reference but now it doesn't work from the SO to the reference. Also the reference's inspector doesn't update when the SO is changed at runtime. That said, damn it's nice already!

laurentopia avatar Jul 30 '24 19:07 laurentopia

Almost there: it works fine from the [Expandable] scriptableobject reference but now it doesn't work from the SO to the reference. Also the reference's inspector doesn't update when the SO is changed at runtime. That said, damn it's nice already!

Hi, I'm a bit confused here.

it doesn't work from the SO to the reference what's the operation here? For what I think, I did:

  1. Click Play to get into play mode
  2. Find the SO, let's say it's named "Main", change the alliaces[0].affinity using inspector to some other value
  3. Click the gameObject, the affinity is correct.
  4. Exit Play mode, the new value is applied

So, what's your operation here so I can re-produce it?

the reference's inspector doesn't update when the SO is changed at runtime.

Do you mean the script changed the So's value like this

[Expandable, Required]
public MCTeam team;

private void Start()
{
    team.alliances[0].affinity = 0;
}

For what I'm testing under IMGUI, it will update the display in the inspector during runtime.

So, any information that helps re-producing it is welcome :)

TylerTemp avatar Aug 02 '24 08:08 TylerTemp

If you reference the SO in a scene gameobject and change the SO, the GO's expanded inspector doesn't update.

laurentopia avatar Aug 03 '24 03:08 laurentopia

This issue is (supposed to be) fixed in 3.4.9. Closed as fixed. If you still face a similar issue please comment below and I will re-open it.

TylerTemp avatar Nov 26 '24 13:11 TylerTemp