Search Unity

Question Unity deletes values in the inspector after pressing play button

Discussion in 'Scripting' started by getmyisland_dev, Jun 30, 2021.

  1. getmyisland_dev

    getmyisland_dev

    Joined:
    Dec 22, 2020
    Posts:
    100
    Hello everyone,

    like the title says Unity deletes everything after I press play.
    That results in a NullReferenceExpection error.

    I assigned a startLocation in the inspector and I'm always getting an error where Unity says the startLocation is null

    Now I'm wondering why Unity is deleting all of my stuff after I press play.
    Here you can see the inspector before:

    and after I press play:


    If it helps I made a custom editor script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. [CustomEditor(typeof(SCP))]
    7. public class SCPeditor : Editor
    8. {
    9.     public override void OnInspectorGUI()
    10.     {
    11.         SCP scpScript = (SCP)target;
    12.  
    13.         scpScript.startLocation = (Node) EditorGUILayout.ObjectField("Starting Node", scpScript.startLocation, typeof(Node), true);
    14.  
    15.         AIManager[] aiManager = Resources.FindObjectsOfTypeAll<AIManager>();
    16.  
    17.         if(aiManager == null)
    18.         {
    19.             EditorGUILayout.HelpBox("Scene must have an AI Manager to populate nodes.", MessageType.Error);
    20.         }
    21.         else
    22.         {
    23.             Node[] nodes = aiManager[0].nodes;
    24.  
    25.             if(scpScript.nodeData == null || scpScript.nodeData.Length != nodes.Length)
    26.             {
    27.                 scpScript.nodeData = new SCP.SCPnodeData[nodes.Length];
    28.                 for(int i = 0; i < nodes.Length; i++)
    29.                 {
    30.                     scpScript.nodeData[i] = new SCP.SCPnodeData();
    31.                 }
    32.             }
    33.  
    34.             EditorGUILayout.BeginVertical();
    35.  
    36.             for (int i = 0; i < nodes.Length; i++)
    37.             {
    38.                 EditorGUILayout.BeginHorizontal();
    39.  
    40.                 EditorGUILayout.TextArea(nodes[i].name);
    41.  
    42.                 scpScript.nodeData[i].node = nodes[i];
    43.                 scpScript.nodeData[i].action = (SCP.Actions) EditorGUILayout.EnumPopup(scpScript.nodeData[i].action);
    44.                 scpScript.nodeData[i].weight = EditorGUILayout.Toggle(scpScript.nodeData[i].weight);
    45.  
    46.                 EditorGUILayout.EndHorizontal();
    47.             }
    48.  
    49.             EditorGUILayout.EndVertical();
    50.         }
    51.     }
    52. }
    All of the stuff in the script above gets reset everytime I press the play button.

    Thanks in advance.
     
    Last edited: Jul 1, 2021
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Do you have more than one SCP in your scene or on a prefab somewhere?

    It's gotta be something because NRE never changes, just like war never changes.

    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.

    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
     
    getmyisland_dev likes this.
  3. getmyisland_dev

    getmyisland_dev

    Joined:
    Dec 22, 2020
    Posts:
    100
    Alright first thanks for your help. I've been trying out a few things you suggested and I'm now stuck with why it is null.
    My answer is everytime I try to play the game Unity resets the stuff I assigned in the inspector. Which results in the NullReferenceExpection error.

    How can I find out why Unity deletes everything I assigned in the inspector? Is there also a step by step guide for this like you suggested in your answer? (I edited the original post to show how my inspector looks before and after I press the play button)

    You asked in your answer if I have multiple objects in the scene and if they are prefabs.
    The answer is I have 3 objects with this script attached and they are all prefabs. Does this make any difference if they are prefabs or not?
     
  4. PizzaPie

    PizzaPie

    Joined:
    Oct 11, 2015
    Posts:
    106
    Unless I miss something you never "serialize" the object (target), to be more precise you never notify the editor to serialize (set dirty) the object. You should look into SerializedObject class and ApplyModifiedProperties . Or if you want to bypass their intented system use directly the EditorUtility.SetDirty.
     
    getmyisland_dev likes this.
  5. getmyisland_dev

    getmyisland_dev

    Joined:
    Dec 22, 2020
    Posts:
    100
    Alright this is probably my mistake, thanks a lot.

    I just did some research, but I couldn't find out what the best way is to implement this.

    I guess I have to probably make the target object "dirty" inside of my editor.

    The only way I found was this:
    Code (CSharp):
    1.     ScriptableObject target = this;
    2.     SerializedObject so = new SerializedObject(target);
    3.    
    4.     // property fields and such
    5.    
    6.     so.ApplyModifiedProperties();
    7.  
    Code (CSharp):
    1.     ScriptableObject target = this;
    2.     SerializedObject so = new SerializedObject(target);
    3.    
    4.     // property fields and such
    5.    
    6.     so.ApplyModifiedProperties();
    7.  
    Visual Studio now tells me there is no such thing like "so.ApplyModifiedProperties();"

    I also can't use "this", because the script itself is not attached to any gameobject.

    I don't really understand how I can implement this into my script.
     
  6. PizzaPie

    PizzaPie

    Joined:
    Oct 11, 2015
    Posts:
    106
    To pick the serialized object do so from the this.serializedObject. To be honest don't remember if this works when you directly modify the target, it is intented to work when you use serialized properties picked from the serialized object. Your best bet by keeping your code is to use the EditorUtility.SetDirty and BeginChangeCheck or GUI.changed.