Float field resets to zero when script is loaded/called.

I’m stumped as to why a script’s float field is zero, when it’s hardcoded to 1.1f, and nothing has access to it, let alone tries to set it to something else. Checking what it has done after it executes, as well as with breakpoints and Debug.Logs, all show that it is zero from the application load.

The basic flow is that it’s a simple upgrade script, that is attached to a List on an UpgradeSO scriptableObject. The CharacterLoader, when loading a character, cycles through the UpgradeSOs, and executes a function on each.

The problem variable:
MoveFaster_10.locomotionMultiplier

public class MoveFaster_10 : Upgrade
{
       private readonly float locomotionMultiplier = 1.1f;

        public override void ExecuteAtStartOfMatch(CharacterPrefab character)
        {
             var animator = character.Animator;

            int anim_locoMultiplier = Animator.StringToHash("LocomotionMultiplier");

            animator.SetFloat(anim_locoMultiplier, locomotionMultiplier);
        }
}
using Sirenix.OdinInspector;
public class UpgradeSO : SerializedScriptableObject
{
        // other stuff

       // MoveFaster_10 is one of the items on this list
        [TypeFilter(nameof(GetFilteredUpgradeList))]
        public List<Upgrade> upgradeList = new List<Upgrade>();
 
}
public class CharacterLoader : MonoBehaviour
{

       public void LoadCharacters()
        {

            // Loads Character
           // assembledCharacter.Upgrades is an UpgradeSO[], one of which has MoveFaster_10

            // Load all upgrades
            foreach(var upgradeSO in assembledCharacter.Upgrades)
            {
                foreach(var upgradeItem in upgradeSO.upgradeList)
                {
                    upgradeItem.ExecuteAtStartOfMatch(characterToLoad);
                }
            }
        }
}

Thanks for any help!

The constructor is run probably only once, then the same object is used again and again, since it is a serialized scriptable object.

Try exiting Unity and restarting. It will likely be 1.1 at that point.

Dunno if this might be happening due to the particulars of Odin and how it displays/handles polymorphic data.

You can get "Unity Default’ polymorphic behaviour by using SerializedReference on the list and just inherit from the the regular ScriptableObject class (you’ll need to make your class System.Serializable as well) and see if you encounter the same issue.

If you don’t, might be worth bringing up with the Odin devs on their Discord.

2 Likes

Ah, yes, this seems to have been the problem. I was afraid Odin would be the issue, but I thought I’d check with Unity/C# guys first. It works as expected now, following your advice.

I had also tried @Kurt-Dekker idea first, but it didn’t seem to change anything. Looks like I was misusing Odin here.

Thanks guys for your help!

1 Like

I wouldn’t say you were misusing Odin, as, well, that’s partly the purpose of their serialisation is to do stuff you normally couldn’t. Though even they will recommend SerializeReference for polymorphic lists of classes or structs, as their own serialization is additional overhead atop of Unity’s existing serialisation. You will need Odin to do polymorphic interfaces however.

Part of me feels like the behaviour you encountered isn’t expected, so it’d be worth bringing up with the devs for more input.

1 Like