2017-12-19 26 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インテル.OnGUI()( でC:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:398) System.Reflection.MonoMethod.Invoke(System.Object obj、BindingFlags invokeAttr、System.Reflection .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 /ユーザ/ builduser/buildslave/AT(System.ObjectのOBJ、のBindingFlags invokeAttr、System.Reflection.Binder バインダー、System.Objectの[]パラメータ、可能System.Globalization.CultureInfo 培養)( (System.Object obj、 System.Object [] parameters)( /Users/builduser/obj/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232) System.Reflection.MethodBase.Invoke (buildslave/mono/build/mcs/class/corlib/System.Reflection/MethodBase.cs:115) UnityEditor.HostView.Invoke(System.String methodName、System.Object obj)(C:/ buildslave/unity/build /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のリストであると考えられます。これは私が立ち往生している場所です。

これは何を引き起こす可能性があると私は何ができるのか、このエラーを修正するためにチェック?

EDIT:this.tracker.activeEditors自体がnullである可能性があります。その場合、例外はeditors.Lengthで発生し、少なくともforループには入るべきではないと思います。 Unityバージョンの変更で行番号が変更された可能性があるので、そのコード内の行は実際に例外の原因ではないかもしれませんが、私はそれを知る方法がありません。

このnullpointerを簡単に修正できないという問題は、コードからの呼び出しがなくてもエディタコードで発生し、何をするべきかわからないということです。this.tracker.activeEditorsまたはその原因が何であれ、正しく配置する必要がありますさあ。

アクティブな編集者がいるように、何かをアクティブにする必要がありますか?

これは私のApply()方法である: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のものなので、直接アクセスすることはできません。割り当てが必要な場所を追跡することはできません。私が知る限り自分で割り当てることはできません。 –

+0

さて、申し訳ありませんが、それを知らなかった。だから私はあなたの質問を再開しました。私は統一されていないので、残念ながら私はあなたの問題を解決することはできません。 –

答えて

0

MattRix's repoから

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()

プレハブを交換する代わりに、新しいプレハブが作成された場合、エラーは表示されません。 コードで、問題が

GameObject newPrefab = PrefabUtility.CreatePrefab(prefabPath + "/" + name + ".prefab", newObject); 
関連する問題