Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Dec 20, 2014 at 06:17 PM by meat5000 for the following reason:

The question is answered.

avatar image
4
Question by Ossi101 · Jun 14, 2014 at 05:30 AM · editorexceptioncomponents

Destroying Components from Editor Script Throwing MissingReferenceException

I'm trying to use a custom editor script to remove multiple BoxCollider2D components on a game object.

I have a script attached to the game object in the scene to which I am adding the components to. I have an editor button that calls this method inside the game object's script.

 public void GenerateWallCollider2D()
     {
         for (int i = 0; i < 4; i++)
         {
             gameObject.AddComponent("BoxCollider2D");
         }
     }

These components appear correctly on the game object. I then have another editor button that calls a method to remove all the BoxCollider2D components that I have added.

 public void Clear()
     {
         BoxCollider2D[] boxCollidersRemove = GetComponents<BoxCollider2D>();
 
         for (int i = 0; i < boxCollidersRemove.Length; i++)
         {
             DestroyImmediate(boxCollidersRemove[i]);
         }
 
     }

This correctly removes all the BoxCollider2D components from the game object but there is a problem. Unity throws an error:

MissingReferenceException: The object of type 'BoxCollider2D' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.

This error only goes away if I remove the DestroyImmediate() line but of course this removes that functionality which is what I'm looking for.

After moving around with where I was keeping my BoxCollider2D[] reference it doesn't seem to matter. Checking if the object in the array is null doesn't solve the issue. TryCatch blocks don't catch the exception ( it acts as though it didn't throw anything ).

From what I could tell it seems like Unity refreshes the game object when a single component is removed, so when it goes to the next index in the array it looks like it's acting as if the object at that index is referenced to nothing. Which would make sense except it still deleted the correct component. This is a problem because if I were to use this during runtime it constantly pauses the game due to this error.

So I'm at a loss as to what the problem is. I feel like I may be misunderstanding the way Unity manages adding and removing components or I'm missing some call in one of the scripts to cement the idea that I am remove a component? Is there a better way to remove multiple components that I'm not aware of? A lot of the questions about this similar problem on here mostly talk about Destroy() which does not work in editor. The others I've read have no answers.

Thanks!

Comment
Add comment · Show 6
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image vexe · Jun 14, 2014 at 06:48 PM 1
Share

Have you tried iterating backwards?

 for (int i = boxCollidersRemove.Length - 1; i > -1; i--)
 {
    DestroyImmediate(boxCollidersRemove[i]);
 }
avatar image Ossi101 · Jun 14, 2014 at 08:08 PM 0
Share

Yes, it produces the same error.

avatar image MoliCat · Dec 20, 2014 at 05:32 PM 5
Share

You should first check unity official scripting guide about
public static function Destroy(obj: Object, t: float = 0.0F): void;

unity remove component

avatar image meat5000 ♦ · Dec 20, 2014 at 05:59 PM 1
Share

Why DestroyImmediate ins$$anonymous$$d of Destroy?

Without reading this entire thread, I would hazard a guess as to that being the problem. I'll go read the QA after I click the button :P

Normally, Destroy takes a frame or so to complete. DestroyImmediate does literally that and so anything which still references the object will run into this problem.

Also you may need to use Destroy(GetComponent(BoxCollider)) I could be wrong.

avatar image StewVanB · Dec 20, 2014 at 07:38 PM 0
Share

DestroyImmediate is used because this is an editor script. The regular Destroy method will never be called in editor executed scripts. This is the reason for the DestroyImmediate.

The reason this is an issue is that Destroy flags objects that it is called on for deletion at the end of the frame. DestroyImmediate deletes the object at that very instant ins$$anonymous$$d of flagging the object for removal.

As another answer to the original issue, if it is still an issue, after calling Destroy you need to repopulate your array of objects. You must do this as you have another script somewhere that has a reference to that object and is trying to do something with it.

Show more comments

1 Reply

  • Sort: 
avatar image
0

Answer by StewVanB · Jun 14, 2014 at 06:45 AM

I wrote this today to see if I could recreate your error. For me this generate no errors. Place this script in your "Assets/Editor" folder. A new menu item will appear in the top bar that says "Test" from here there are two operations. AddCollider and DelCollider. Add will add a BoxCollider to every object in the scene. Delete will remove all colliders from every object in the scene.

 using UnityEngine;
 using System.Collections;
 using UnityEditor;
 
 public class ComponentEditor : MonoBehaviour {
     
     public void doAddComponent(){
     
         GameObject[] theList = GameObject.FindObjectsOfType<GameObject>();
         foreach(GameObject obj in theList){
             obj.AddComponent<BoxCollider>();
         }
     }
     
     public void doDelComponent(){
     
         Collider[] theList = (Collider[])Component.FindObjectsOfType<Collider>();
         foreach(Collider col in theList){
             DestroyImmediate(col);
         }
     }
     
 }


--Basic editor GUI for "ComponentEditor.cs" --This should go in the "Editor" folder.

 using UnityEngine;
 using UnityEditor;
 using System.Collections;
 
 [CustomEditor(typeof(ComponentEditor))]
 public class ComponentEditorVisuals : Editor {
     
     public override void OnInspectorGUI(){
         ComponentEditor myScript = (ComponentEditor)target;
         EditorGUILayout.BeginHorizontal();
         if(GUILayout.Button("Add Collider")){
             myScript.doAddComponent();
         }
         if(GUILayout.Button("Del Colliders")){
             myScript.doDelComponent();
         }
         EditorGUILayout.EndHorizontal();
     }
 }


Comment
Add comment · Show 10 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Ossi101 · Jun 14, 2014 at 07:48 AM 0
Share

Unfortunately Unity still gives me the same error with those changes.

avatar image StewVanB · Jun 14, 2014 at 02:46 PM 0
Share

Place a Debug.Log right after you make the BoxCollider array that prints boxColliderRemove[i].gameObject.name to see if the list is being populated correctly.

avatar image Ossi101 · Jun 14, 2014 at 06:01 PM 0
Share

The array is being populated correctly. I put Debug.Log before and after the DestroyImmediate() and it showed that each component in the array was getting set to null after being destroyed. However when I cleared the colliders and put the inspector of the object into debug mode, it showed that the array contained elements that were considered "$$anonymous$$issing" by Unity. So to me it seems like the issue happens inside DestroyImmediate(). Setting each element to null after destroying it gives the correct result in the debug view in the inspector, however it does not solve the error since Unity throws an error before I can modify the element.

avatar image StewVanB · Jun 15, 2014 at 04:19 AM 0
Share

What is the end goal for this code? Since it is an editor script it can only be used in the editor and not in play mode. This makes me assume that you are just using it to make your life easier by mass adding/removing colliders?

avatar image Ossi101 · Jun 15, 2014 at 04:40 AM 0
Share

The end goal is already met so yes, it is to easily create and clear colliders on an object. It works without issues already I just don't understand why I'm getting this error and would like to know. It just doesn't make sense to me.

Show more comments

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

"ArgumentException: method arguments are incompatible" for Analytics Event Tracker parameter 6 Answers

how to fix the "unityexception : launching ios project via xcode failed" exception ? 0 Answers

Permanent handles (when object is not selected) 1 Answer

Check if a script is running in editor or game 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges