1
\$\begingroup\$

I have two scripts, one is located at:

Assets / Scriptable Objects / ...

while the other one is located at:

Assets / Scripts / ...

I have the first script encapsulated on a namespace.

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

namespace VoidlessUtilities
{
[CreateAssetMenu]
public class LevelFlowData : BaseNodeEditorData<BaseLevelNode, LevelFlowEditorAttributes>
{
    private const string MENU_ITEM_PATH = "Create / ScriptableObjects / LevelFlowData";
    private const string NEW_ASSET_PATH = "ScriptableObjects / Level Flow Data";

    [SerializeField] private string _name;
    private RootLevelNode _root;

    /// <summary>Gets and Sets name property.</summary>
    public string name
    {
        get { return _name; }
        set { _name = value; }
    }

    /// <summary>Gets and Sets root property.</summary>
    public RootLevelNode root
    {
        get { return _root; }
        set { _root = value; }
    }

    [MenuItem(MENU_ITEM_PATH)]
    public static void CreateAsset()
    {
        LevelFlowData scriptableObject = ScriptableObject.CreateInstance<LevelFlowData>() as LevelFlowData;
        AssetDatabase.CreateAsset(scriptableObject, AssetDatabase.GenerateUniqueAssetPath(NEW_ASSET_PATH));
    }

    public BaseLevelFlowNode GetLevelFlow()
    {
        BaseLevelFlowNode rootLevelFlow = null;

        if(root != null)
        {
            rootLevelFlow = root.GetNode();
        }
        else
        {
            Debug.LogError("[LevelFlowData] Data has no RootLevelFlowNode saved");
        }

        return rootLevelFlow as RootLevelFlowNode;
    }
}
}

And the other one is using the same namespace, which is a namespace I use for my custom scripts, but the only difference is that LevelFlowData's location is not under Scripts.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VoidlessUtilities;

public class TestLevelController : Singleton<TestLevelController>
{
    [SerializeField] private LevelFlowData _levelFlowData;
    [SerializeField] private List<GameObject> _testViews;

    /// <summary>Gets and Sets levelFlowData property.</summary>
    public LevelFlowData levelFlowData
    {
        get { return _levelFlowData; }
        protected set { _levelFlowData = value; }
    }

    /// <summary>Gets and Sets testViews property.</summary>
    public List<GameObject> testViews
    {
        get { return _testViews; }
        set { _testViews = value; }
    }

#region UnityMethods:
    void OnEnable()
    {
        BaseInteractable.onTriggeredEvent += (int _eventID, bool _triggered)=> { Debug.Log("[TestLevelController] Event Triggered: " + _eventID); };
    }

    void OnDisable()
    {
        BaseInteractable.onTriggeredEvent -= (int _eventID, bool _triggered)=> { Debug.Log("[TestLevelController] Event Triggered: " + _eventID); };
    }

    /// <summary>TestLevelController's' instance initialization.</summary>
    void Awake()
    {

    }

    /// <summary>TestLevelController's starting actions before 1st Update frame.</summary>
    void Start ()
    {

    }

    /// <summary>TestLevelController's tick at each frame.</summary>
    void Update ()
    {

    }
#endregion

#region PublicMethods:
    public void EnableView(int _index)
    {
        testViews.SetAllActive(false);
        testViews[_index].SetActive(true);
    }
#endregion

#region PrivateMethods:

#endregion
}

Do I need to move LevelFlowData to Scripts, and make platform independet compilation (e.g., #if UNITY_EDITOR) encapsulation for UnityEditor namespace usage? Or is there another point I am missing?

This is the specific error log:

Assets/Scripts/Scene Controllers/TestLevelController.cs(10,27): error CS0246: The type or namespace name `LevelFlowData' could not be found. Are you missing an assembly reference?

Thanks in advance.

\$\endgroup\$
1

1 Answer 1

1
\$\begingroup\$

So, the reason why the namespaces are not detected is due to the order of compilation of scripts that makes non-Editor scripts have no reference of Editor scripts..

So, to solve it, I just had to modify the non-Editor script, to now receive a Scriptable object, instead of a LevelFlowData (since that ScriptableObject had dependencies on Editor scripts).

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VoidlessUtilities;
using VoidlessNodes.LevelFlowNodes;
//using VoidlessEditorWindow;
//using VoidlessUtilities.VoidlessNodeEditor;

public class TestLevelController : Singleton<TestLevelController>
{
    [SerializeField] private ScriptableObject _levelFlowData;
    [SerializeField] private List<GameObject> _testViews;
    [SerializeField] private BaseLevelFlowNode _levelFlowRoot;

    /// <summary>Gets and Sets levelFlowData property.</summary>
    public ScriptableObject levelFlowData
    {
        get { return _levelFlowData; }
        protected set { _levelFlowData = value; }
    }

    /// <summary>Gets and Sets testViews property.</summary>
    public List<GameObject> testViews
    {
        get { return _testViews; }
        set { _testViews = value; }
    }

    /// <summary>Gets and Sets levelFlowRoot property.</summary>
    public BaseLevelFlowNode levelFlowRoot
    {
        get { return _levelFlowRoot; }
        set { _levelFlowRoot = value; }
    }

#region UnityMethods:
    void OnEnable()
    {
        BaseInteractable.onTriggeredEvent += (int _eventID, bool _triggered)=> { Debug.Log("[TestLevelController] Event Triggered: " + _eventID); };
    }

    void OnDisable()
    {
        BaseInteractable.onTriggeredEvent -= (int _eventID, bool _triggered)=> { Debug.Log("[TestLevelController] Event Triggered: " + _eventID); };
    }
}

And then use the Inspector script I made for that class as a layer to deal with some Editor utilities, casting the ScriptableObject to LevelFlowData to still have the functionalities I expected.

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

[CustomEditor(typeof(TestLevelController))]
public class TestLevelControllerInspector : Editor
{
    private const string REPLACE_VIEW_TAG = "View_";
    private const string OPEN_LEVEL_EDITOR = "Open Level Flow Editor";
    private const string UPDATE_LEVELFLOW = "Update Level Flow Data";
    private TestLevelController testLevelController;

    /// <summary>Sets target property.</summary>
    void OnEnable()
    {
        testLevelController = target as TestLevelController;
    }

    /// <summary>OnInspectorGUI override.</summary>
    public override void OnInspectorGUI()
    {
        /// Do your stuff here:

        DrawDefaultInspector();

        if(testLevelController.testViews.Count > 0)
        {
            for(int i = 0; i < testLevelController.testViews.Count; i++)
            {
                if(testLevelController.testViews[i] != null)
                {
                    if(GUILayout.Button(testLevelController.testViews[i].name.Replace(REPLACE_VIEW_TAG, " ")))
                    {
                        testLevelController.EnableView(i);
                    }
                }   
            }
        }

        if(testLevelController.levelFlowData != null)
        {
            if(GUILayout.Button(OPEN_LEVEL_EDITOR))
            {
                if((testLevelController.levelFlowData is LevelFlowData))
                {
                    LevelFlowEditor.OpenNodeEditorWindowWithData(testLevelController.levelFlowData as LevelFlowData);
                }
                else
                Debug.LogError("[TestLevelControllerInspector] ScriptableObject provided is not of type LevelFlowData");
            }
            if(GUILayout.Button(UPDATE_LEVELFLOW))
            {
                if((testLevelController.levelFlowData is LevelFlowData))
                {
                    LevelFlowData data = testLevelController.levelFlowData as LevelFlowData;
                    testLevelController.levelFlowRoot = data.GetLevelFlow();

                    testLevelController.levelFlowRoot.Tick();
                }
                else
                Debug.LogError("[TestLevelControllerInspector] ScriptableObject provided is not of type LevelFlowData");
            }
        }
    }
}

Hope it solves similar issues to other users.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .