Search Unity

Bug onAfterDeserialize keep sending Error: object reference not set to an instance of an object

Discussion in 'Scripting' started by catcat52009, Aug 28, 2021.

  1. catcat52009

    catcat52009

    Joined:
    Mar 18, 2018
    Posts:
    9
    I copied and some scripts in my previous project form 2019 to 2020 editor
    and change them to a new class, try to make a new system

    everything work fine but the part of onAfterDeserialize keep saying:
    Error: object reference not set to an instance of an object
    so I added a ContextMenu to check if it work or not
    it work perfectly, but the error pop up when it complied or start the game every time
    not showing when i call it by ContextMenu or other methods

    all my classes are serializable, just like my previous project
    still can run if i ignore this error

    Code (CSharp):
    1. [CreateAssetMenu(menuName = "Skill System/Rune Database",order = 1)]
    2. public class RuneDatabase : ScriptableObject, ISerializationCallbackReceiver
    3. {
    4.     public BaseRune[] runes;
    5.     public Dictionary<int, BaseRune> GetSkill = new Dictionary<int, BaseRune>();
    6.  
    7.  
    8.     [ContextMenu("Updata IDs")]
    9.     public void UpdateID()
    10.     {
    11.         for (int i = 0; i < runes.Length; i++)
    12.         {
    13.             if (runes[i].rune.id != i)
    14.                 runes[i].rune.id = i;
    15.         }
    16.     }
    17.  
    18.     [ContextMenu("Debug")]
    19.     public void OnAfterDeserialize()
    20.     {
    21.         for (int i = 0; i < runes.Length; i++)
    22.         {
    23.             runes[i].rune.id = i;
    24.             GetSkill.Add(i, runes[i]);
    25.         }
    26.         foreach (var item in GetSkill)
    27.         {
    28.             Debug.Log(item.Key + "- " + item.Value);
    29.         }
    30.     }
    31.  
    32.     public void OnBeforeSerialize()
    33.     {
    34.         GetSkill = new Dictionary<int, BaseRune>();
    35.     }
    36.  
    37. }
    Code (CSharp):
    1. public abstract class BaseRune : ScriptableObject
    2. {
    3.     public Rune rune;
    4. }
    5.  
    6. [System.Serializable]
    7. public class Rune
    8. {
    9.     public int id;
    10.     public string skillName;
    11.     [SerializeReference]
    12.     public Sprite icon;
    13.     [TextArea(2, 5)]
    14.     public string description;
    15.     public int skillLevel = 1;
    16.     public int maxLevel = 30;
    17.     public List<tag> tags;
    18.     public List<SkillProperty> properties;
    19.     [Header("Damages")]
    20.     public List<DamagePrecentage> damagePrecentages;
    21.     public List<AdditionalDamage> additionalDamages;
    22.     float convertedDamage = 0;
    23.  
    24.     [System.Serializable]
    25.     public class SkillProperty
    26.     {
    27.         public Property Property;
    28.         [SerializeField]
    29.         protected float value;
    30.         [SerializeField]
    31.         protected float growth;
    32.         [SerializeField]
    33.         protected int step = 1;
    34.         public float multiplier = 1;
    35.     }
    36.  
    37.  
    38. }
    39.  
    40. [System.Serializable]
    41. public class DamagePrecentage
    42. {
    43.     public DamageType type;
    44.     [Range(0, 1)]
    45.     public float precentage;
    46. }
    47. [System.Serializable]
    48. public class AdditionalDamage
    49. {
    50.     public DamageType type;
    51.     public int minDamage, maxDamage;
    52. }
    53.  
    54.  
    55.  
    56.  

    is that a 2020 editor issue or something?
     
    Last edited: Aug 28, 2021
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    Could be editor behavior changed, could be the serialization process changed.

    Whatever it is, it's a NullRef, so the same exact steps apply. It might just be a default-ish kinda condition where one of the serialized fields aren't initialized if they didn't exist before (eg., you added, removed or renamed a field).

    Therefore, I include my standard NullReference blurb:

    The answer is always the same... ALWAYS. It is the single most common error ever.

    Don't waste your life spinning around and round on this error. Instead, learn how to fix it fast... it's EASY!!

    Some notes on how to fix a NullReferenceException error in Unity3D
    - also known as: Unassigned Reference Exception
    - also known as: Missing Reference Exception
    - also known as: Object reference not set to an instance of an object

    http://plbm.com/?p=221

    The basic steps outlined above are:
    - Identify what is null
    - Identify why it is null
    - Fix that.

    Expect to see this error a LOT. It's easily the most common thing to do when working. Learn how to fix it rapidly. It's easy. See the above link for more tips.

    You need to figure out HOW that variable is supposed to get its initial value. There are many ways in Unity. In order of likelihood, it might be ONE of the following:

    - drag it in using the inspector
    - code inside this script initializes it
    - some OTHER external code initializes it
    - ? something else?

    This is the kind of mindset and thinking process you need to bring to this problem:

    https://forum.unity.com/threads/why-do-my-music-ignore-the-sliders.993849/#post-6453695

    Step by step, break it down, find the problem.

    Here is a clean analogy of the actual underlying problem of a null reference exception:

    https://forum.unity.com/threads/nul...n-instance-of-an-object.1108865/#post-7137032
     
  3. catcat52009

    catcat52009

    Joined:
    Mar 18, 2018
    Posts:
    9
    thanks for ur reply, i ve seen this somewhere else

    i removed all the variables/class in my object
    only the id
    it still same

    so i create a new 2019 project for test
    any similar variables/class wont be error
    even some aren't serializable
    then i transfer to 2020
    this error come again w/o change anything

    seems this is a 2020 editor issue
    but the weird thing is:
    i updated my previous project form 2019 to 2020
    no error
     
    Last edited: Aug 29, 2021
  4. catcat52009

    catcat52009

    Joined:
    Mar 18, 2018
    Posts:
    9
    so i found out the problem is my file name of the script
    it should be the same as the scriptable object, cant be the class if u put it in a same script
     
    Kurt-Dekker likes this.
  5. catcat52009

    catcat52009

    Joined:
    Mar 18, 2018
    Posts:
    9
    AND.... it appear again after i sleep
     
  6. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hi, that requirement is needed for ScriptableObjects and Monobehaviours, but it shouldn't be needed for plain serializable classes. It'd be easier if you shared the stack trace, or at least the line of the error. That said, I think it might be the runes array.

    ScriptableObjects sometimes start with a null array. Maybe it's because they are deserialized from empty data, so there's no entry for the array field and it stays null; but I've seen some cases that contradict this idea. I don't know if Unity devs know about it; I've tried to make a case to report this, but I haven't been able to reproduce it consistently. Anyway, the solution is easy: initialize your array fields to an empty array in their definition. So,
    runes = System.Array.Empty<BaseRune>();
    .

    I found this post searching for SerializeReference in the forum, so I noticed you have a SerializeReference attribute on the icon field, which is a Sprite. Sprite is a UnityEngine.Object, so it doesn't support that attribute; maybe that could also be tripping the serialization? I'd advise to remove the attribute anyway.

    EDIT
    Also, if it does turn out to be the array, and you are able to reproduce it consistently, I'd love to know about it; I've been wondering about it for a year and a half.