Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

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

Discussion in 'Scripting' started by MichaelTGD, Sep 28, 2021.

  1. MichaelTGD

    MichaelTGD

    Joined:
    Oct 24, 2019
    Posts:
    16
    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<Upgrades> 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

    Code (CSharp):
    1.    
    2. public class MoveFaster_10 : Upgrade
    3. {
    4.        private readonly float locomotionMultiplier = 1.1f;
    5.  
    6.         public override void ExecuteAtStartOfMatch(CharacterPrefab character)
    7.         {
    8.              var animator = character.Animator;
    9.  
    10.             int anim_locoMultiplier = Animator.StringToHash("LocomotionMultiplier");
    11.  
    12.             animator.SetFloat(anim_locoMultiplier, locomotionMultiplier);
    13.         }
    14. }


    Code (CSharp):
    1.  
    2. using Sirenix.OdinInspector;
    3. public class UpgradeSO : SerializedScriptableObject
    4. {
    5.         // other stuff
    6.  
    7.        // MoveFaster_10 is one of the items on this list
    8.         [TypeFilter(nameof(GetFilteredUpgradeList))]
    9.         public List<Upgrade> upgradeList = new List<Upgrade>();
    10.  
    11. }


    Code (CSharp):
    1. public class CharacterLoader : MonoBehaviour
    2. {
    3.  
    4.        public void LoadCharacters()
    5.         {
    6.  
    7.             // Loads Character
    8.            // assembledCharacter.Upgrades is an UpgradeSO[], one of which has MoveFaster_10
    9.  
    10.             // Load all upgrades
    11.             foreach(var upgradeSO in assembledCharacter.Upgrades)
    12.             {
    13.                 foreach(var upgradeItem in upgradeSO.upgradeList)
    14.                 {
    15.                     upgradeItem.ExecuteAtStartOfMatch(characterToLoad);
    16.                 }
    17.             }
    18.         }
    19. }
    Thanks for any help!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,767
    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.
     
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,895
    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.
     
    Bunny83 and MichaelTGD like this.
  4. MichaelTGD

    MichaelTGD

    Joined:
    Oct 24, 2019
    Posts:
    16
    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!
     
    Kurt-Dekker likes this.
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,895
    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.
     
    MichaelTGD likes this.