- Home /
Why using UnityEditor.SceneManagement; is gray like not in use and give error when building my game ?
It's not showing errors in the visual studio I can compile this script fine. I can play the game fine in the unity editor no errors in the unity editor.
But when trying to compile the game in the Build Settings... window then only then it's showing me in the unity editor error saying : Assets\My Scripts\ObjectsReplace.cs(6,19): error CS0234: The type or namespace name 'SceneManagement' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)
But the SceneManagement does exist in the script it's gray like not using it but exist., I don't have any errors in the visual studio.
If I remove the SceneManagement and then trying to build my game then it will give me like 10 errors of places in the script that need the SceneManagement. But it's all in the unity editor and only when trying to build my game.
I can use this script fine in the editor I can run and play the game fine no errors or problems in the visual studio or the editor. ONLY when trying to build then it's showing the errors.
I can't figure out why this script and not others. Tried many times to shut down the visual studio and to open it again same for the unit editor. I can't figure out what is going on.
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEditor.SceneManagement;
public class ObjectsReplace : MonoBehaviour
{
public GameObject prefabToInit;
public bool deleteAllShaders = false;
private const string c_doorRight = "Door_Right";
private const string c_doorLeft = "Door_Left";
private const string c_doorShieldFxLocked = "DoorShieldFXLocked";
public List<GameObject> FindDoors(string[] SpecificParents)
{
GameObject[] doorsLeft = GameObject.FindGameObjectsWithTag(c_doorLeft);
GameObject[] doorsRight = GameObject.FindGameObjectsWithTag(c_doorRight);
List<GameObject> allDoors = doorsLeft.Union(doorsRight).ToList();
if (deleteAllShaders == false)
{
List<GameObject> toRemove = new List<GameObject>();
for (int i = 0; i < allDoors.Count; i++)
{
bool match = true;
for (int x = 0; x < SpecificParents.Length; x++)
{
match &= allDoors[i].transform.parent.name != SpecificParents[x];
}
if (match)
{
toRemove.Add(allDoors[i]);
}
}
foreach (var it in toRemove)
{
allDoors.Remove(it);
}
}
return allDoors;
}
public void DeleteAllShaders()
{
if(deleteAllShaders == true)
{
UpdateOrAddShaderPrefabToDoors();
}
}
public void UpdateOrAddShaderPrefabToDoors()
{
var allDoors = FindDoors(new string[]{ "Wall_Door_Long_01", "Wall_Door_Long_02", "Wall_Interior_Door_02" });
HashSet<GameObject> prefabParentsOfDoorsNeedRemove = new HashSet<GameObject>();
allDoors.ForEach(doorGameObject =>
{
List<GameObject> shadersChildren = new List<GameObject>();
for (int i=0; i<doorGameObject.transform.childCount ;i++)
{
if (doorGameObject.transform.GetChild(i).name.StartsWith(c_doorShieldFxLocked))
{
shadersChildren.Add(doorGameObject.transform.GetChild(i).gameObject);
}
}
foreach (GameObject shader in shadersChildren)
{
GameObject outermostPrefabInstanceRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(shader);
prefabParentsOfDoorsNeedRemove.Add(outermostPrefabInstanceRoot);
}
});
foreach (GameObject parent in prefabParentsOfDoorsNeedRemove)
{
Modify(parent, RemoveFunc);
}
HashSet<GameObject> prefabParentsOfDoors = new HashSet<GameObject>();
allDoors.ForEach(doorGameObject =>
{
GameObject outermostPrefabInstanceRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(doorGameObject);
prefabParentsOfDoors.Add(outermostPrefabInstanceRoot);
});
if (deleteAllShaders == false)
{
foreach (GameObject parent in prefabParentsOfDoors)
{
AddShaderToPrefab(parent);
}
}
}
private void AddShaderToPrefab(GameObject child)
{
Modify(child, AddShaderToAllDoorsFunc);
}
private GameObject AddShaderToAllDoorsFunc(GameObject prefab)
{
var children = prefab.GetComponentsInChildren<Transform>();
//Debug.Log($"Total child count before:{children.Count()}");
int doorsFound = 0;
foreach (Transform trans in children)
{
if (trans.name == c_doorLeft || (trans.name == c_doorRight))
{
//Debug.Log("Found door, adding");
GameObject shader = GetDoorShaderPrefab();
// clone prefab and attach to parent
Instantiate(shader, trans);
doorsFound++;
}
}
children = prefab.GetComponentsInChildren<Transform>();
//Debug.Log($"Total child count after:{children.Count()}, doors found:{doorsFound}");
return prefab;
}
private GameObject GetDoorShaderPrefab()
{
string[] shieldPrefab = AssetDatabase.FindAssets(c_doorShieldFxLocked);
//Debug.Assert(shieldPrefab.Length == 1, "Expected exactly 1 shield like this...");
string shieldGuid = shieldPrefab[0];
string prefabPath = AssetDatabase.GUIDToAssetPath(shieldGuid);
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
//Debug.Assert(prefab != null, "Expected prefab to load");
return prefab;
}
private GameObject RemoveFunc(GameObject prefab)
{
var children = prefab.GetComponentsInChildren<Transform>();
//Debug.Log($"child count:{children.Count()}");
foreach (Transform trans in children)
{
if (trans.name.StartsWith(c_doorShieldFxLocked))
{
//Debug.Log("Found door shader");
DestroyImmediate(trans.gameObject);
}
}
children = prefab.GetComponentsInChildren<Transform>();
//Debug.Log($"child count:{children.Count()}");
return prefab;
}
private void Modify(GameObject parentPrefab, Func<GameObject,GameObject> modifyActionOnPrefab)
{
// Get the Prefab Asset root GameObject and its asset path.
string assetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(parentPrefab);
// Load the contents of the Prefab Asset.
GameObject prefab = PrefabUtility.LoadPrefabContents(assetPath);
//PrefabUtility.UnpackPrefabInstance(mostPrefabInstanceRoot, PrefabUnpackMode.Completely, UnityEditor.InteractionMode.AutomatedAction);
prefab = modifyActionOnPrefab(prefab);
PrefabUtility.SaveAsPrefabAsset(prefab, assetPath);
PrefabUtility.UnloadPrefabContents(prefab);
}
}
I'm using this script also with a small editor script : The editor script is in the Editor folder :
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
[CustomEditor(typeof(ObjectsReplace))]
public class ObjectsReplaceEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
ObjectsReplace myScript = (ObjectsReplace)target;
if (GUILayout.Button("Add"))
{
myScript.UpdateOrAddShaderPrefabToDoors();
}
GUILayout.Space(20);
if(GUILayout.Button("Delete all shaders"))
{
myScript.DeleteAllShaders();
}
}
}
Last night I installed unity 2019.3.2f1 personal and then it did import to the scripts in my project. Then I tried to back to my 2019.2.5f1 personal version.
Maybe this changes of the unity editor versions did something to the script ? The strange thing is that it's only happens on this script the MonoBehaviour ObjectsReplace.
This is the errors I'm getting :
UnityEditor.BuildPlayerWindow+BuildMethodException: 2 errors at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (UnityEditor.BuildPlayerOptions options) [0x00242] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:190 at UnityEditor.BuildPlayerWindow.CallBuildMethods (System.Boolean askForBuildLocation, UnityEditor.BuildOptions defaultBuildOptions) [0x0007f] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:95 UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
And
Assets\My Scripts\ObjectsReplace.cs(6,19): error CS0234: The type or namespace name 'SceneManagement' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)
I don't see this errors in the visual studio !
Answer by rh_galaxy · Feb 23, 2020 at 07:36 PM
You should do this, and fix any errors that now present itself in the final/real build. Because namespace UnityEditor can only be used in the editor, not the real build.
#if UNITY_EDITOR
using UnityEditor;
#endif
The same for
using UnityEditor.SceneManagement;
using UnityEditorInternal;
Answer by jimmiewalker653 · Nov 26, 2020 at 02:03 PM
using UnityEditor will still result in build errors. You'll need 2 scripts, one for what you need within the Unity Editor and the other for what is needed to make the application work. The scripts needed within the Unity Editor will need to be in a folder named "Editor". Any folder titled Editor will be ignored when a build is compiled and will prevent errors that pop up from using UnityEditor.
Side note: If you do not need to use Unity Editor then use UnityEngine.Scene$$anonymous$$anagement instead. You should only need to use UnityEditor if you are needing to modify the interface of Unity directly.