2017-12-19 46 views
1

모델을 수정하기 위해 꽤 복잡한 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>(); 
     } 
+0

아니오()에 'Apply

GameObject newPrefab = PrefabUtility.ReplacePrefab(newObject, targetPrefab); 

대체하여 해결된다, 오히려 this.tracker.activeEditors'가 널 '을 의미한다. –

+0

그러면 어떻게 해결할 수 있습니까? 그것은 내 코드가 아니고 UnityEditor 's이기 때문에 직접 할당 할 수있는 위치를 추적하기 위해 액세스 할 수 없으며 내가 아는 한 자신을 할당 할 수 없습니다. –

+0

죄송합니다. 몰랐습니다. 그래서 나는 당신의 질문을 재개했습니다. 나는 화합에 경험이 없으므로, 불행히도 당신의 문제를 해결할 수는 없습니다. –

답변

0

.

프리 팹을 교체하는 대신 새 프리 팹이 생성되면 오류가 표시되지 않습니다. 그래서 코드 이 문제

GameObject newPrefab = PrefabUtility.CreatePrefab(prefabPath + "/" + name + ".prefab", newObject);