1
\$\begingroup\$

I have an array of ScritableObject's, which should only be displayed in the inspector if a boolean is true. How would I do this? With my current code, I get an error saying:

Cannot implicitly convert type Tile to `Tile[]

This is my current code:

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

[CreateAssetMenu (fileName="Data", menuName="Tiles/Map", order=1)] 
public class Tile : ScriptableObject {

    public ETile eTile;     
    public Sprite sprite;

    [Space(5), Header("Variety")]   
    public bool variety;

    [Range(0f, 1f)]     
    public float varietyChance;
    public Tile[] varietyTiles; <---- This should be hidden if variety is true 
}

public enum ETile {
    Water, 
    Grass
}

[CustomEditor(typeof(Tile))]
public class MyScriptEditor : Editor {

    override public void OnInspectorGUI() {
        var tile = target as Tile;

        tile.variety = EditorGUILayout.Toggle("Hide Fields", tile.variety);

        if (tile.variety) {
            tile.varietyTiles = (Tile)EditorGUILayout.ObjectField("Tile", tile, typeof(Tile), allowSceneObjects: true);         }
        }
    }
}
\$\endgroup\$
1
\$\begingroup\$

Found it, small modification to Tim C. The line:

EditorGUILayout.PropertyField(tileProperty, includeChildren:true)

Would in this case always return false, therefor the if-statement is never run, which makes that the ApplyModifiedProperties method of the serializedObject is never called. Making that the value of the new property is never stored in the tile.varietyTiles. Therefor, the correct code would be:

tile.variety = EditorGUILayout.Toggle("Enable", tile.variety);
if (tile.variety) {
    SerializedProperty tileProperty = serializedObject.FindProperty("varietyTiles");
    EditorGUILayout.PropertyField(tileProperty, includeChildren: true);
    if(tileProperty.hasChildren)
    {
        serializedObject.ApplyModifiedProperties();
    }
}

Explanation

This code first checks whether you want to display the property or not. After that, on line 3 and 4, it receives the value of the current property and generates a new property with the values of the old one. In the if-statement, it's check whether and tileProperty contains children. If true, the value of the tile.varietyTiles is updated with the new content of tileProperty.

\$\endgroup\$
0
\$\begingroup\$

You can't do this with ObjectField because Arrays are not Objects. You need to use a PropertyField instead of an ObjectField, which is more generic and can handle properties of any type.

Corrected code:

[CustomEditor(typeof(MyTile))]
public class MyScriptEditor : Editor
{

    override public void OnInspectorGUI()
    {
        var tile = target as MyTile;

        tile.variety = EditorGUILayout.Toggle("Hide Fields", tile.variety);

        if (tile.variety)
        {
            SerializedProperty tileProperty = serializedObject.FindProperty("varietyTiles");
            if(EditorGUILayout.PropertyField(tileProperty, includeChildren:true))
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ Returns error: "Cannot convert type UnityEngine.Object to Tile[]" \$\endgroup\$ – FlorisdG Oct 21 '18 at 21:27
  • \$\begingroup\$ Fixed and updated. \$\endgroup\$ – Tim C Oct 21 '18 at 23:57
  • \$\begingroup\$ Kind of fixed. If I try this, the array keeps getting cleared, beause it instantiates a new array \$\endgroup\$ – FlorisdG Oct 24 '18 at 12:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.