Home > other >  How to make that if includeChildren is false to be able to check each single individual toggle of th
How to make that if includeChildren is false to be able to check each single individual toggle of th

Time:07-09

The problem is in the loop when i set the includeChildren bool to false again i can't then select individual toggles from the include1 array because includeChildren set the include1[i] to false all the time.

if(includeChildren)
{
    include1[i] = true;
}
else
{
    include1[i] = false;
}
    
include1[i] = EditorGUILayout.Toggle("Include Children", include1[i], GUILayout.ExpandWidth(true));

The full script :

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

public class RenameSelected : EditorWindow
{
    private static readonly Vector2Int size = new Vector2Int(500, 500);
    private string childrenPrefix;
    private int startIndex;
    private bool showPosition = false;
    private bool includeChildren = false;
    private bool[] include1;
    private bool a = false;
    private GameObject[] objects;
    private Vector2 scrollPos;

    [MenuItem("GameObject/Rename Selected")]
    public static void Init()
    {
        EditorWindow window = GetWindow<RenameSelected>();
        window.minSize = size;
        window.maxSize = size;
    }

    private void OnSelectionChange()
    {
        objects = Selection.gameObjects;
    }

    private void OnEnable()
    {
        objects = Selection.gameObjects;
        include1 = new bool[objects.Length];
    }

    public void OnGUI()
    {
        GUILayout.Space(10);
        childrenPrefix = EditorGUILayout.TextField("Rename prefix", childrenPrefix);
        startIndex = EditorGUILayout.IntField("Start index", startIndex);
        includeChildren = EditorGUILayout.Toggle("Include Children", includeChildren);

        if (objects.Length == 0)
        {
            showPosition = false;
        }
        GUILayout.Space(20);
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.GetControlRect(true, 16f, EditorStyles.foldout);
        Rect foldRect = GUILayoutUtility.GetLastRect();
        if (Event.current.type == EventType.MouseUp && foldRect.Contains(Event.current.mousePosition))
        {
            showPosition = !showPosition;
            GUI.changed = true;
            Event.current.Use();
        }

        showPosition = EditorGUI.Foldout(foldRect, showPosition, "Objects");
        GUILayout.Space(2);

        if (showPosition)
        {
            EditorGUI.indentLevel  ;

            scrollPos =
            EditorGUILayout.BeginScrollView(scrollPos);
            for (int i = 0; i < objects.Length; i  )
            {
                EditorGUIUtility.labelWidth = 50;

                EditorGUILayout.BeginHorizontal();
                {
                    GUILayoutOption[] options = { GUILayout.MaxWidth(300.0f), GUILayout.MinWidth(300.0f) };
                    objects[i] = (GameObject)EditorGUILayout.ObjectField(i.ToString(), objects[i], typeof(GameObject), true, options);
                    EditorGUIUtility.labelWidth = 112;
                    
                    if(includeChildren)
                    {
                        include1[i] = true;
                    }
                    else
                    {
                        include1[i] = false;
                    }

                    include1[i] = EditorGUILayout.Toggle("Include Children", include1[i], GUILayout.ExpandWidth(true));
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndScrollView();

            EditorGUI.indentLevel--;
        }

        GUILayout.FlexibleSpace();
        if (GUILayout.Button("Rename Objects"))
        {
            
        }

        Repaint();
    }
}

Some screenshot of what i'm trying to archive :

The main goal is to be able to rename multiple selection of gameobjects.

Selections

About the toggles :

I want to make that if the global variable includeChildren is true then try to get all children of all selected gameobjects in the array objects : check all the toggles of all the objects and try to get all the children of each gameobject if there is children then build a foldout tree for each gameobject so i can see all the children.

If the global variable includechildren is not checked is false the i want to be able to check set false/true each individual gameobject by checking/unchecking the toggle checkbox near it.

CodePudding user response:

Your main issue is in your if part. What are you doing right now - you are syncing (OnGUI is called several times per frame) every bool array element with the "global" value many times per second. That's why you cannot change any of the elements individually.

What you need to do:

  • in your OnGUI method always operate only the current value of your bool array elements
  • handle the moment when your "global" value was changed and modify the whole bool array

I will add code partially. I think it will be enough:

...
void OnGUI()
{
    ...
    bool newIncludeChildrenGlobal = EditorGUILayout.Toggle("Include Children", includeChildren);
    if (newIncludeChildrenGlobal != includeChildren)
    {
        ProcessGlobalToggleChanged(newIncludeChildrenGlobal);
    }
    includeChildren = newIncludeChildrenGlobal;

    ...

// completely remove commented code part
//
// if(includeChildren)
// {
//     include1[i] = true;
// }
// else
// {
//     include1[i] = false;
// }
    ...
}

void ProcessGlobalToggleChanged(bool newValue)
{
    for (int i = 0; i < include1.Length; i  )
    {
        include1[i] = newValue;
    }
}

If I understood what you want correctly, it should do the trick.

  • Related