Home > Enterprise >  "The type or namespace name 'SceneAsset' could not be found" error when trying t
"The type or namespace name 'SceneAsset' could not be found" error when trying t

Time:11-07

So in this script below, I used the SceneAsset reference in the C# script in Unity and it worked well when playing from the editor.

However, when I tried to build my game, it wouldn't work as I got errors from the console, saying

The type or namespace name 'SceneAsset' could not be found".

Is it a bug or it's something I'm doing wrong?

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;

public class ProvincePinScript : MonoBehaviour
{
    public int ActiveWorldProvinceID;
    public SceneAsset[] WorldProvinces;

    // We can set up a pin that can take bananaman to certain provinces or countries! :)
    public void Begin()
    {
        Invoke("Travel", 4f);
    }
    
    public void Travel()
    {
        SceneManager.LoadScene(WorldProvinces[ActiveWorldProvinceID].name);
    }
}

CodePudding user response:

To reference SceneAsset you added a using reference to UnityEditor. This will work fine in the editor, but once you build the final game, all references to UnityEditor are removed.

You normally add scripts intended to run in the editor to a folder in your project named Editor. When building, Unity won’t include anything in that folder. But you’ve circumvented that mechanism, and you’re left with a UnityEditor stub that doesn’t contain anything.

The documentation here goes in to a little more detail about the SceneAsset.

In general, you would point to a scene by either its build index or scene name, using the SceneManager.LoadSceneAsync, as an example, which is detailed here.

Here's an example of a hack that I mocked up (written, untested, but should do the job). This should allow you to use the UnityEditor.SceneAsset in the Inspector and will serialise the scene names to a List<string> that you can use in the runtime script. As mentioned, this is just a hack I mocked up, for the exercise. I make no assertion that this is indeed a good idea, but in theory it will allow you to drag and drop scene asset objects into the Inspector, instead of manually writing out the scene names as strings.

#if UNITY_EDITOR
using UnityEditor;
#endif

using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections.Generic;

public class ProvincePinScript : MonoBehaviour
#if UNITY_EDITOR
    , ISerializationCallbackReceiver
#endif
{
    public int ActiveWorldProvinceID;
#if UNITY_EDITOR
    public SceneAsset[] WorldProvinces;
#endif

    [HideInInspector, SerializeField]
    private List<string> _worldProvinces;

    // We can set up a pin that can take bananaman to certain provinces or countries! :)
    public void Begin ( )
    {
        Invoke ( "Travel", 4f );
    }

    public void Travel ( )
    {
        SceneManager.LoadScene ( _worldProvinces [ ActiveWorldProvinceID ] );
    }

#if UNITY_EDITOR
    public void OnAfterDeserialize ( ) => FillScenes ( );
    public void OnBeforeSerialize ( ) => FillScenes ( );
    public void OnValidate ( ) => FillScenes ( );

    private void FillScenes ( )
    {
        if ( _worldProvinces is null )
            _worldProvinces = new ( );
        _worldProvinces.Clear ( );
        foreach ( var s in WorldProvinces )
            _worldProvinces.Add ( s.name );
    }
#endif
}
  • Related