모델을 수정하기 위해 꽤 복잡한 Unity Editor 스크립트가 있습니다. 자산 폴더에 새 오브젝트를 작성한 다음 인스펙터에서 모델, 일부 수정 자 및 적용 키를 사용하여 새 오브젝트를 작성하는 데 사용됩니다. 그러면 모델이 수정되고 생성 된 객체가 새 객체 조립식으로 바뀝니다.UnityEditor.InspectorWindow.GetEditorsWithPreviews의 NullReferenceException
적용 누르면, 방법 Apply()
가 호출되고 그 실행 한 후,이 밖으로 콘솔 인쇄 :
는 NullReferenceException : 개체 참조가 객체의 인스턴스 UnityEditor.InspectorWindow.GetEditorsWithPreviews 로 설정되지 (C 에서 : /buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs : 515) (UnityEditor.Editor [] 편집자) UnityEditor.InspectorWindow.DrawPreviewAndLabels() (C에서 /buildslave/일치/빌드/편집기/모노/관리자/InspectorWindow.cs : 612) UnityEditor.InspectorW System.Reflection.MonoMethod.Invoke (OBJ으로 System.Object, BindingFlags의 invokeAttr,하는 System.Reflection (: 398 /buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs C에서) indow.OnGUI() .Binder binder, System.Object [] 매개 변수, System.Globalization.CultureInfo culture) ( /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222) TargetInvocationException로서 재 _ 생하십시오. 호출 대상에 의해 예외가 _ 생했습니다. System.Reflection.MonoMethod.Invoke (OBJ으로 System.Object, BindingFlags의 invokeAttr, System.Reflection.Binder 바인더은 System.Object [] 파라미터 선택 System.Globalization.CultureInfo 배양) ( /사용자/builduser/buildslave/AT System.Reflection.MethodBase.Invoke (System.Object obj, System.Object [] 매개 변수) ( /사용자/builduser/build/mcs/class/corlib/System.Reflection/MonoMethod.cs : 232) System.Reflection.MethodBase.Invoke buildslave/monity/build/mcs/class/corlib/System.Reflection/MethodBase.cs : 115) UnityEditor.HostView.Invoke (System.String methodName, System.Object obj) /Editor/Mono/HostView.cs:272) UnityEditor.HostView.Invoke (System.String methodName) (에 있음)C : /buildslave/unity/build/Editor/Mono/HostView.cs : 265) UnityEditor.HostView.InvokeOnGUI (rect onGUIPosition) ( C : /buildslave/unity/build/Editor/Mono/HostView.cs : 232)
비슷한 오류가 있지만 다른 상황과 대답이없는 2014 년 질문이 있습니다. 대답은 here입니다.
예외가 발생할 수있는 항목에 대해 MattRix's decompiled Unity repo을 검사했는데 레포 버전이 2017.1.0f3이고 2017.1.1f1에있는 경우에도 문제가 발생한 위치를 찾은 것 같습니다. DrawPreviewsAndLabels()
에서 :
IPreviewable[] editorsWithPreviews = this.GetEditorsWithPreviews(this.tracker.activeEditors);
그리고 다음
GetEditorsWithPreviews(Editor[] editors){
...
for (int i = 0; i < editors.Length; i++)
{
Editor editor = editors[i];
...
예외가 라인 Editor editor = editors[i];
에 호출 할 것으로 보인다. 이것은 내가 this.tracker.activeEditors
이라는 요소가 null
인 목록이라고 생각하게합니다. 여기가 내가 붙어있는 곳이야.
무엇이 문제의 원인 일 수 있으며이 오류를 해결하기 위해 수행 할 수있는 작업은 무엇입니까?
편집 : 아마도 this.tracker.activeEditors
자체가 null이라는 의미입니다. 그 경우에, 나는 예외가 editors.Length
에 일어날 것이라고 생각하고 적어도 for 루프로 들어가면 안된다. Unity 버전 변경으로 라인 번호가 변경되었을 수 있으므로 해당 코드의 라인이 실제로 예외의 원인이 아닐 수도 있지만이를 알 방법이 없습니다.
이 nullpointer를 쉽게 고칠 수 없다는 문제는 코드에서 호출하지 않고 편집기 코드에서 발생하며 무엇을 해야할지 모르기 때문에 this.tracker.activeEditors
또는 그 원인을 정확하게 지정해야합니다. 있다.
활발한 편집자가있을 수 있도록 그렇게 활동적으로 만들어야합니까?
이 내 Apply()
방법 :
private void Apply(List<Mesh> meshes, List<Material[]> materials, Chamferer chamferer)
{
GameObject newObject = Instantiate(chamferer.gameObject);
Object targetPrefab = PrefabUtility.GetPrefabObject(chamferer);
string name = chamferer.source.name;
//Delete previous meshes
MeshFilter[] filters = newObject.transform.GetComponentsInChildren<MeshFilter>();
for (int i = 0; i < filters.Length; i++)
{
filters[i].transform.SetParent(null);
GameObject.DestroyImmediate(filters[i].gameObject);
}
string prefabPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(targetPrefab));
Mesh prev = null;
//Add new meshes
for (int i = 0; i < meshes.Count; i++)
{
Mesh mesh = meshes[i];
Mesh newMesh = EdgeChamfer.AddChamfer(mesh, chamferer.scale);
GameObject obj = new GameObject(mesh.name);
obj.transform.SetParent(newObject.transform);
MeshFilter mf = obj.AddComponent<MeshFilter>();
MeshRenderer mr = obj.AddComponent<MeshRenderer>();
mf.sharedMesh = newMesh;
mr.sharedMaterials = materials[i];
//Adds mesh under prefab
if (i == 0)
{
AssetDatabase.CreateAsset(newMesh, prefabPath + "/" + name + ".asset");
prev = newMesh;
}
else
{
AssetDatabase.AddObjectToAsset(newMesh, prev);
prev = newMesh;
}
}
AssetDatabase.SaveAssets();
GameObject newPrefab = PrefabUtility.ReplacePrefab(newObject, targetPrefab);
//Renames the object accordingly
string renamingerr = AssetDatabase.RenameAsset(prefabPath + "/" + newPrefab.name + ".prefab", "Chamfered" + name);
if (renamingerr != "")
{
Debug.Log(renamingerr);
}
Selection.activeObject = newPrefab;
EditorGUIUtility.PingObject(newPrefab);
GameObject.DestroyImmediate(newObject);
}
그리고 전체 GetEditorsWithPreviews()
MattRix's repo에서 :
OnInspectorGUI()
이 뭔가를 시도 할 때 오류가 표시 될 수 있음을 표시
public IPreviewable[] GetEditorsWithPreviews(Editor[] editors)
{
IList<IPreviewable> list = new List<IPreviewable>();
int num = -1;
for (int i = 0; i < editors.Length; i++)
{
Editor editor = editors[i];
num++;
if (!(editor.target == null))
{
if (!EditorUtility.IsPersistent(editor.target) || !(AssetDatabase.GetAssetPath(editor.target) != AssetDatabase.GetAssetPath(editors[0].target)))
{
if (EditorUtility.IsPersistent(editors[0].target) || !EditorUtility.IsPersistent(editor.target))
{
if (!this.ShouldCullEditor(editors, num))
{
if (!(editors[0] is AssetImporterEditor) || editor is AssetImporterEditor)
{
if (editor.HasPreviewGUI())
{
list.Add(editor);
}
}
}
}
}
}
}
foreach (IPreviewable current in this.m_Previews)
{
if (current.HasPreviewGUI())
{
list.Add(current);
}
}
return list.ToArray<IPreviewable>();
}
아니오()에 'Apply
대체하여 해결된다, 오히려 this.tracker.activeEditors'가 널 '을 의미한다. –
그러면 어떻게 해결할 수 있습니까? 그것은 내 코드가 아니고 UnityEditor 's이기 때문에 직접 할당 할 수있는 위치를 추적하기 위해 액세스 할 수 없으며 내가 아는 한 자신을 할당 할 수 없습니다. –
죄송합니다. 몰랐습니다. 그래서 나는 당신의 질문을 재개했습니다. 나는 화합에 경험이 없으므로, 불행히도 당신의 문제를 해결할 수는 없습니다. –