【发布时间】:2020-02-22 23:52:35
【问题描述】:
在我使用 SceneManagement 的脚本中:
using UnityEditor.SceneManagement;
但它是灰色的,就像我没有在脚本中使用它一样。但是,如果我将删除该行:
using UnityEditor.SceneManagement;
它不会在 Visual Studio 中显示错误,但如果我现在尝试在编辑器中编译游戏,它将在需要 SceneManagement 的地方的控制台中显示 10 个错误。
此脚本之前从未出现过错误。它是在我尝试构建游戏时开始的。
我的部分脚本的屏幕截图。 SceneManagement 是灰色的,好像不需要或正在使用,但它是:
以及编辑器中的建筑设置窗口:
我试图关闭退出 Visual Studio 并在编辑器中双击脚本重新打开它,但它没有改变任何东西。
完整的脚本:
using System;
using System.Collections;
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);
}
}
这也是我在单声道脚本中使用的编辑器脚本:
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();
}
}
}
再次!发生了什么:
我可以在编辑器中运行游戏,没有任何问题。没有错误就没有问题。
我可以在visual studio中编译和保存脚本没有任何问题没有错误没有问题。
我不能只在编辑器中构建游戏!!!构建游戏时,它仅在统一编辑器控制台中显示错误!视觉工作室中仍然没有错误。我可以在编辑器中玩游戏 我无法构建游戏。
使用 UnityEngine 或 UnityEditor 的脚本中存在命名空间 SceneManagement,但这不是问题。问题是无论我将 UnityEngine 或 UnityEditor 与 SceneManagement 一起使用,SceneManagement 都是灰色的,就像没有使用一样,但它正在使用中!
如果我删除删除单声道和编辑器的脚本,我可以构建游戏!
我还不明白为什么在构建它时在构建设置中给我这个错误,但它们没有在视觉工作室中显示!
【问题讨论】:
-
当您有特定于平台的定义时,可能会发生这种情况。 ObjectsReplace.cs 的其余部分是什么样的?
-
@Iggy 我刚刚编辑了我的问题添加了完整的脚本。但是为什么它没有在 visua lstudio 中显示错误,而只在编辑器中显示?
-
也许问题是我现在使用的是统一版本 2019.3.2f1 个人而不是 2019.2.5f1 个人?也许它改变了一些东西?几个小时前我更新了我的统一,它确实为脚本导入了。