0
\$\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\$
0
\$\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\$

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.