How to Get Component in Edit Mode?

gameObject.GetComponenet() works well in Play Mode, but when I go back to Edit Mode all references to components is destroyed. When I tryed to gameObject.GetComponent() in Edit Mode, I receive Exception: “MissingReferenceException: The object of type has been destroyed but you are still trying to access it.”. This is beheviour of custom scripts. Built in scripts works fine because they survive exiting Play Mode an all links are fine.

// Work but gameObject must be selected all the time
_components = Selection.activeObject.GetComponents<Component>();
                
// Dont work in Edit Mode
_components = gameObject.GetComponents<Component>();

 // If there is object in hierarchy with same name all goes wrong
_components = GameObject.Find(_gameObjectName).GetComponents<Component>();

Code:

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace Grave.Tools.SaveInPlayMode
{

    public class SaveInPlayModeScript : MonoBehaviour
    {

        [SerializeField] private bool _isSaveInPlayMode = true;
        
        [Header("Debug")]
        [SerializeField] private Component[] _components;
        [SerializeField] private List<string> _serializedComponents = new();
        
        private void Awake()
        {

            // Grab _components only once on Playmode Entered
            _components = GetComponents<Component>();
            
            EditorApplication.playModeStateChanged += OnPlayModeStateChanged_EventHandler;
        }

        private void OnPlayModeStateChanged_EventHandler(PlayModeStateChange state)
        {

            if (!_isSaveInPlayMode)
            {
                return;
            }

            if (state == PlayModeStateChange.ExitingPlayMode)
            {
                _serializedComponents.Clear();
                SerializeAllFieldsInJson();
            }
            else if (state == PlayModeStateChange.EnteredEditMode)
            {

                // _components = Selection.activeObject.GetComponents<Component>();
                Debug.Log(GetType().Name);
                //var script = Editor.FindObjectOfType<SaveInPlayModeScript>();
                _components = GameObject.Find(GetType().Name).GetComponents<Component>();
                
                DeserializeAllFieldsInJson();
            }
        }

        private void SerializeAllFieldsInJson()
        {

            foreach (Component component in _components)
            {

                string toJson = EditorJsonUtility.ToJson(component);
                _serializedComponents.Add(toJson);
            }
        }

        private void DeserializeAllFieldsInJson()
        {

            for (int i = 0; i < _components.Length; i++)
            {
                //Debug.Log(_components*.GetType().Name);*

try
{
_ = components*.name;
_
}*

catch (Exception e)
{
Debug.LogWarning($“{e.GetType().Name}: {e.Message}”);
}

if (!_components*) continue;*

EditorJsonUtility.FromJsonOverwrite(serializedComponents*,
_components);*

}
}
}
}_

Not totally sure what you mean by this:

When I tryed to GetComponent() in Edit Mode, I receive Exception

So you’re invoking GetComponent() in a script right, where the reference for whatever component you’re using won’t be set until runtime- if you want a reference to be set in Play mode, you’ll have to use public variables that can be set in the inspector.

This is just because unless a script is meant to modify or extend the editor itself, the code doesn’t run until you press Play. Am I understanding the situation right?

How I solve this problem:

     private Component[] FindThisGameObject()
    {

        // Work but gameObject must be selected all the time
        //_components = Selection.activeObject.GetComponents<Component>();

        // Dont work in Edit Mode
        //_components = gameObject.GetComponents<Component>();

        // If object in hierarchy with same name it is bad
        //_components = GameObject.Find(_gameObjectName).GetComponents<Component>();

        var allGameObjects = GameObject.FindObjectsOfType<GameObject>();
        var allGameObjectsWithThisName = allGameObjects.Where(obj => obj.name == 
        _gameObjectName);

        foreach (GameObject go in allGameObjectsWithThisName)
        {

            if (go.TryGetComponent(out SaveInPlayModeScript script))
            {
                if (script.id == id)
                {
                    return go.GetComponents<Component>();
                }
            }
        }

        return null;
    }

write the new one it is scrapped- 1