1
\$\begingroup\$

If it's needed I will add the completed script code of the Prefab Replace EditorWindow type.

I packed exported the project to a file and uploaded the packed file it's 31MB only. My unity pack

In EditorWindow script:

for (var i = selection.Count - 1; i >= 0; --i)
{
      var selected = selection[i];
      _components = selected.GetComponents(typeof(MonoBehaviour));

      foreach (var comp in _components)
      {
              _newObject.Init(comp);
      }
}
  • _newObject is an instantiated prefab
  • _components is a Component[] array

Using either typeof(MonoBehaviour) or typeof(Component) I will get the same null exception later.

When I'm using a break point to debug I see that in components there are 3 items. And they are not null.

Then I have a Extension class:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;

public static class Extension
{
    public static T AddComponent<T>(this GameObject go, T toAdd) where T : Component
    {
        return go.AddComponent<T>().GetCopyOf(toAdd);
    }

    public static void Init<T>(this GameObject go, T comp) where T : Component
    {
        go.AddComponent(comp);
    }

    public static T GetCopyOf<T>(this Component comp, T other) where T : Component
    {
        if (comp != null)
        {
            Type type = comp.GetType();
            if (type != other.GetType()) return null; // type mis-match

            const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default | BindingFlags.DeclaredOnly;

            var pinfos = type.GetProperties(flags);
            foreach (var pinfo in pinfos.Where(pinfo => pinfo.CanWrite))
            {
                try
                {
                    pinfo.SetValue(comp, pinfo.GetValue(other, null), null);
                }
                catch { } // In case of NotImplementedException being thrown. For some reason specifying that exception didn't seem to catch it, so I didn't catch anything specific.
            }

            var finfos = type.GetFields(flags);
            foreach (var finfo in finfos)
            {
                finfo.SetValue(comp, finfo.GetValue(other));
            }
        }

        return comp as T;
    }
}

When using a break point I can see that inside the Init method that go and comp are not null. Then it's moving to the top method AddComponent and also there both go and toAdd are not null.

But when it's getting to the method GetCopyOf then comp is null at the first line it's null:

if (comp != null)

Already on this line comp is null. I can't figure out why it's null only at this method.

NullReferenceException: Object reference not set to an instance of an object

The full stack message:

Extension.GetCopyOf[T] (UnityEngine.Component comp, T other) (at Assets/Scripts/Extension.cs:23)
Extension.AddComponent[T] (UnityEngine.GameObject go, T toAdd) (at Assets/Scripts/Extension.cs:12)
Extension.Init[T] (UnityEngine.GameObject go, T comp) (at Assets/Scripts/Extension.cs:17)
PrefabReplace.InstantiatePrefab (System.Collections.Generic.IReadOnlyList`1[T] selection) (at Assets/Editor/PrefabReplace.cs:222)
PrefabReplace.Replacing () (at Assets/Editor/PrefabReplace.cs:144)
PrefabReplace.OnGUI () (at Assets/Editor/PrefabReplace.cs:44)
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <d7ac571ca2d04b2f981d0d886fa067cf>:0)
UnityEditor.HostView.Invoke (System.String methodName, System.Object obj) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:342)
UnityEditor.HostView.Invoke (System.String methodName) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:336)
UnityEditor.HostView.InvokeOnGUI (UnityEngine.Rect onGUIPosition, UnityEngine.Rect viewRect) (at C:/buildslave/unity/build/Editor/Mono/HostView.cs:310)
UnityEditor.DockArea.DrawView (UnityEngine.Rect viewRect, UnityEngine.Rect dockAreaRect, System.Boolean customBorder, System.Boolean floatingWindow, System.Boolean isBottomTab) (at C:/buildslave/unity/build/Editor/Mono/GUI/DockArea.cs:361)
UnityEditor.DockArea.OldOnGUI () (at C:/buildslave/unity/build/Editor/Mono/GUI/DockArea.cs:320)
UnityEngine.Experimental.UIElements.IMGUIContainer.DoOnGUI (UnityEngine.Event evt, UnityEngine.Matrix4x4 worldTransform, UnityEngine.Rect clippingRect, System.Boolean isComputingLayout) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:266)
UnityEngine.Experimental.UIElements.IMGUIContainer.HandleIMGUIEvent (UnityEngine.Event e, UnityEngine.Matrix4x4 worldTransform, UnityEngine.Rect clippingRect) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:438)
UnityEngine.Experimental.UIElements.IMGUIContainer.HandleIMGUIEvent (UnityEngine.Event e) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:421)
UnityEngine.Experimental.UIElements.IMGUIContainer.HandleEvent (UnityEngine.Experimental.UIElements.EventBase evt) (at C:/buildslave/unity/build/Modules/UIElements/IMGUIContainer.cs:401)
UnityEngine.Experimental.UIElements.EventDispatcher.ProcessEvent (UnityEngine.Experimental.UIElements.EventBase evt, UnityEngine.Experimental.UIElements.IPanel panel) (at C:/buildslave/unity/build/Modules/UIElements/EventDispatcher.cs:511)
UnityEngine.Experimental.UIElements.EventDispatcher.Dispatch (UnityEngine.Experimental.UIElements.EventBase evt, UnityEngine.Experimental.UIElements.IPanel panel, UnityEngine.Experimental.UIElements.DispatchMode dispatchMode) (at C:/buildslave/unity/build/Modules/UIElements/EventDispatcher.cs:307)
UnityEngine.Experimental.UIElements.BaseVisualElementPanel.SendEvent (UnityEngine.Experimental.UIElements.EventBase e, UnityEngine.Experimental.UIElements.DispatchMode dispatchMode) (at C:/buildslave/unity/build/Modules/UIElements/Panel.cs:176)
UnityEngine.Experimental.UIElements.UIElementsUtility.DoDispatch (UnityEngine.Experimental.UIElements.BaseVisualElementPanel panel) (at C:/buildslave/unity/build/Modules/UIElements/UIElementsUtility.cs:245)
UnityEngine.Experimental.UIElements.UIElementsUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at C:/buildslave/unity/build/Modules/UIElements/UIElementsUtility.cs:68)
UnityEngine.GUIUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at C:/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:179)
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Extension methods can be called on null objects, this means that that the only way comp can be null inside getCopyOf is when GameObject#AddComponent<T>() returns null.

This could happen because 1.) said gameobject already has a component of type T, 2.) The Component is an abstract one and can't be instantiated or 3.) The type is Component

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .