How to acces to a data list in a custom editor from a editorwindow

Help, support and information for our Game Framework Unity Asset.
If posting about the assets in the extras bundle then please use the appropriate forum.
Post Reply
Fabb
Posts: 30
Joined: Mon May 16, 2016 10:04 am

How to acces to a data list in a custom editor from a editorwindow

Post by Fabb » Fri Mar 08, 2019 7:08 pm

Hello Mark,

I customize in the Editor a level editor for my game, i can serialize all my level data parameters in the level_x file.
I'd like to add an EditorWindow which permit drawing elements, and store in a list in my serialize file below.
I don't know how to link my CustomLevel class (my editor data manager) with an EditorWindow.

How to do the link ?

My custom class managed with the inspector launch correctly the EditorWindow:

Code: Select all

       

   if (GUILayout.Button("Open Grid Window", GUILayout.Width(255)))
           {
               GridWindowEditor window = (GridWindowEditor)EditorWindow.GetWindow(typeof(GridWindowEditor));
               window.BeginWindows();
           }
Inside these class i have a lot of serialized loader and writer.

My GridWindowsEditor class is something like this :

Code: Select all

public class GridWindowEditor : EditorWindow
{
   public static GridWindowEditor gridWindow;

   ==> ??how to get a reference to my custom class (CustomLevel)

  private static void OpenWindow()
   {
       GridWindowEditor window = GetWindow<GridWindowEditor>();
       window.titleContent = new GUIContent("Grid Window Editor");
       gridWindow.Populate();

   }
   private void OnEnable()
   {
   }
   private void OnGUI()
   {
   }
}
I'd try a public static CustomLevelEditor refLevelEditor; to reference my target class but i don't know how to instance them.

Do you have an idea ?

Thanks.
Fabb

mahewitt
Site Admin
Posts: 245
Joined: Thu May 05, 2016 8:06 pm

Re: How to acces to a data list in a custom editor from a editorwindow

Post by mahewitt » Mon Mar 11, 2019 8:34 pm

Hi,

Not 100% sure that I follow what you are trying to do, however you can load things like levels using the standard Resources.Load() e.g.

CustomLevel level = Resources.Load<CustomLevel>("path");

You could also just try adding a public List<CustomLevel> and drag and drop them over. Not sure if that will give what you need?

Mark

Fabb
Posts: 30
Joined: Mon May 16, 2016 10:04 am

Re: How to acces to a data list in a custom editor from a editorwindow

Post by Fabb » Sat Mar 16, 2019 10:11 am

Hi Mark,

Thanks for your response.
I want to add a List<Object> in the CustomLevel and save data in the Level_x.asset.


Code: Select all


[Serializable]
    public class Tile : ScriptableObject
    {
        [SerializeField]
        public Rect rect;
        [SerializeField]
        public string title;
        [SerializeField]
        public bool isDragged;
        [SerializeField]
        public bool isSelected;

        public GUIStyle style;
        public GUIStyle defaultmyTileStyle;
        public GUIStyle selectedmyTileStyle;

        public Action<Tile> OnRemoveTile;

        public Tile(Vector2 position, float width, float height, GUIStyle myTileStyle, GUIStyle selectedStyle, Action<Tile> OnClickRemoveTile)
        {
            int _size = 32;
            
            Vector2 aligned = new Vector2(Mathf.Floor(position.x / _size) * _size + _size / 2.0f,
                              Mathf.Floor(position.y / _size) * _size + _size / 2.0f);
            //rect = new Rect(position.x, position.y, width, height);
            rect = new Rect(aligned.x, aligned.y, width, height);
            style = myTileStyle;
            defaultmyTileStyle = myTileStyle;
            selectedmyTileStyle = selectedStyle;
            OnRemoveTile = OnClickRemoveTile;
            Debug.Log("CustomLevel Create Rect : " + rect.x + " / " + rect.y);

        }

        public void Drag(Vector2 delta)
        {
            //int _size = 32;
            //Debug.Log("//*** " + delta.x + " / " + delta.y);
            //Vector2 aligned = new Vector2(delta.x , delta.y );
            rect.position += delta;
            //rect.position += aligned;
            //Vector2 aligned = new Vector2(Mathf.Floor(rect.position.x + delta.x / _size) * _size + _size / 2.0f,
            //      Mathf.Floor(rect.position.y + delta.y/ _size) * _size + _size / 2.0f);
            //rect.position = aligned;
        }

        public void Draw()
        {
            Texture2D tex= (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/Game/Graphics/Obstacles/bottom/bottom_v1_01.png", typeof(Texture2D));
            GUI.DrawTexture(rect, tex, ScaleMode.ScaleToFit, true, 1.0f);
        }

        public bool ProcessEvents(Event e)
        {
            switch (e.type)
            {
                case EventType.MouseDown:
                    if (e.button == 0)
                    {
                        if (rect.Contains(e.mousePosition))
                        {
                            isDragged = true;
                            GUI.changed = true;
                            isSelected = true;
                            style = selectedmyTileStyle;
                        }
                        else
                        {
                            GUI.changed = true;
                            isSelected = false;
                            style = defaultmyTileStyle;
                        }
                    }

                    if (e.button == 1 && isSelected && rect.Contains(e.mousePosition))
                    {
                        ProcessContextMenu();
                        e.Use();
                    }
                    break;

                case EventType.MouseUp:
                    isDragged = false;
                    break;

                case EventType.MouseDrag:
                    if (e.button == 0 && isDragged)
                    {
                        Drag(e.delta);
                        e.Use();
                        return true;
                    }
                    break;
            }

            return false;
        }

        private void ProcessContextMenu()
        {
            GenericMenu genericMenu = new GenericMenu();
            genericMenu.AddItem(new GUIContent("Remove tile"), false, OnClickRemoveTile);
            genericMenu.ShowAsContext();
        }

        private void OnClickRemoveTile()
        {
            if (OnRemoveTile != null)
            {
                OnRemoveTile(this);
            }
        }
    }

My CustomLevelEditor.cs contains :

Code: Select all

        SerializedProperty _myTiles;
In the enable part, i have :

Code: Select all

            _myTiles = serializedObject.FindProperty("_myTiles");

I'm don't sure that le List is really save in Level_x.asset, i know that array works but i'd like to store a List object, more easy to manage.


In my EditorWindows (launch with a button in the inspector), i have found a methode to get the instance of the inpectorWindow (refCustomLevelEditor), and i can access and modify data.

Code: Select all

        Debug.Log("GridWindowEditor/onEnable : " + (refCustomLevelEditor.serializedObject.targetObject as CustomLevel).PlayerForceSpeed);
How store and access List object with the same method ?

Thanks ;)
Fabb

ps: i tried to load with your tips, it works to access but i dont find method to manage List.

Fabb
Posts: 30
Joined: Mon May 16, 2016 10:04 am

Re: How to acces to a data list in a custom editor from a editorwindow

Post by Fabb » Sun Mar 17, 2019 10:14 am

Hi,

I have a solution.
Store a list object in a level_x file works and i can access it from another class using the instance.
My trouble was you can add an element with .add method, you must use insert method, after all list class variable element are stored.

Code: Select all

(refCustomLevelEditor.serializedObject.targetObject as CustomLevel).myTilesList.Insert(0,new Tile(mousePosition, 100, 100, myTileStyle, selectedmyTyleStyle, OnClickRemoveTile));

I just look for a method to automatically save my level_x modifications without the ctrl+s ...

serializedObject.Update (); on the onInpectorGui and serializedObject.ApplyModifiedProperties(); doesnt automatically save data on the disk.

i tested

Code: Select all

EditorGUI.BeginChangeCheck();

Code: Select all

            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
                GUI.FocusControl(null);
            }
            serializedObject.ApplyModifiedProperties();
            base.OnInspectorGUI ();

            if (EditorApplication.isPlaying)
                Repaint();

mahewitt
Site Admin
Posts: 245
Joined: Thu May 05, 2016 8:06 pm

Re: How to acces to a data list in a custom editor from a editorwindow

Post by mahewitt » Sun Mar 17, 2019 2:43 pm

Think I misunderstood you original question, but glad you have a solution. Can be a bit messy working with custom editors, but check out also some of the editor code provided if you see similar behaviour from any of my stuff. Should hopefully be clear enough to read.

Fabb
Posts: 30
Joined: Mon May 16, 2016 10:04 am

Re: How to acces to a data list in a custom editor from a editorwindow

Post by Fabb » Fri Mar 22, 2019 6:42 pm

Hi Mark,

Do you know the method which permit to record level_x modification ?

saveprefs method is not the good one and i dont find any save method like the ctrl+s key.

Thanks ;)
Fabb

mahewitt
Site Admin
Posts: 245
Joined: Thu May 05, 2016 8:06 pm

Re: How to acces to a data list in a custom editor from a editorwindow

Post by mahewitt » Mon Mar 25, 2019 2:05 pm

At edit time the values should be saved automatically but you might need to use ApplyModifiedProperties or the like. Run time that won't work and so you would need to use some other serialisation method such as saving to json (or possibly the BinaryFormatter).

When is it you need to update the values and how are you trying so far?

Fabb
Posts: 30
Joined: Mon May 16, 2016 10:04 am

Re: How to acces to a data list in a custom editor from a editorwindow

Post by Fabb » Tue Mar 26, 2019 7:03 pm

Hi Mark,

I finally understood how it works, i saw a unity video on editor.
I put the correct pattern and it perfectly works.

I try to enhance the customeleveleditor with a graphic level editor to put different gameobject type on the screen.
I'm working too on sequencial level editor (with task & node) to internally manage the level timeline.

I'm not able to industrialize and made it so generic like you, but it can be a roadmap element for you.
I'll send you more information later ;)

ps: you have this error below on your website when we submit after a post reply

Code: Select all

[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions_messenger.php on line 506: count(): Parameter must be an array or an object that implements Countable
[phpBB Debug] PHP Warning: in file [ROOT]/includes/functions.php on line 1836: Cannot modify header information - headers already sent by (output started at [ROOT]/includes/functions.php:3268)

mahewitt
Site Admin
Posts: 245
Joined: Thu May 05, 2016 8:06 pm

Re: How to acces to a data list in a custom editor from a editorwindow

Post by mahewitt » Sun Mar 31, 2019 9:57 am

Great . Any further info would be much apåpreciated.

Thanks for the heads up on the error. Not seen that myself, but will try and find what the problem is.

Mark

Post Reply