8

Is there any way to remove component from Gameobject using script?

For example:

I add FixedJoint to player by script, connect object to it (for grabbing), and when I drop it I want to remove the FixedJoint (because, I can't just "disable" joint). How can I do it?

Programmer
  • 121,791
  • 22
  • 236
  • 328
Alexandr Köln
  • 144
  • 2
  • 2
  • 8

2 Answers2

14

Yes, you use the Destroy function to destroy/remove a component from a GameObject. It can be used to remove Component or GameObject.

Add Component:

gameObject.AddComponent<FixedJoint>();

Remove Component:

FixedJoint fixedJoint = GetComponent<FixedJoint>();
Destroy(fixedJoint);
Programmer
  • 121,791
  • 22
  • 236
  • 328
  • 1
    @AlexandrKöln You son't change the title of your question to "SOLVED". You [accept](http://meta.stackexchange.com/a/5235) the answer and the system will mark it as solved. – Programmer Feb 09 '17 at 08:18
  • 2
    Woah, I had no idea about this! Also, according to http://stackoverflow.com/questions/26243500/add-remove-components-in-runtime?rq=1 you might want to use DestroyImmediate in certain cases. Might be good for the inquirerer to know if you're gonna be adding and removing components a lot! – Fredrik Schön Feb 09 '17 at 08:22
  • 2
    @Fredrik `DestroyImmediate` is another way to do it. It's recommended not to use it since it destroys right away while `Destroy` will destroy in the next frame. It's good for OP to that it exists though. – Programmer Feb 09 '17 at 08:30
  • Alright, how come it's not recommended though? Does it come at a higher price? EDIT: From documentation: `You are strongly recommended to use Object.Destroy always. Destroy is executed at a safe time. DestroyImmediate happens immediately.` – Fredrik Schön Feb 09 '17 at 08:32
  • 1
    I don't know why. Unity has there own reason for warning us on that. It also says "This function should only be used when writing editor code". So, there you go. I've never had to use `DestroyImmediate` before. – Programmer Feb 09 '17 at 08:39
4

To experiment with Programmers correct answer, I created an extension-method so you can use gameObject.RemoveComponent(/* true if immediate */) because I felt there should a method like this.

If you'd want to use it you'd create a new class anywhere with the following code:

using UnityEngine;

public static class ExtensionMethods
{
    public static void RemoveComponent<Component>(this GameObject obj, bool immediate = false)
    {
        Component component = obj.GetComponent<Component>();

        if (component != null)
        {
            if (immediate)
            {
                Object.DestroyImmediate(component as Object, true);
            }
            else
            {
                Object.Destroy(component as Object);
            }

        }
    }
}

and then to use it like you'd do with AddComponent<>()

gameObject.RemoveComponent<FixedJoint>();

It will be accessible in any method that extends MonoBehaviour. You can also add more methods to this static extension class, just use the "this"-syntax as parameter to extend a certain Unity type. For instance if you add following method (from the extension method tutorial)

public static void ResetTransformation(this Transform trans)
{
    trans.position = Vector3.zero;
    trans.localRotation = Quaternion.identity;
    trans.localScale = new Vector3(1, 1, 1);
}

you would use transform.ResetTransformation(); in any of your scripts to invoke it. (Making the class look like:)

using UnityEngine;

public static class ExtensionMethods
{
    public static void RemoveComponent<Component>(this GameObject obj, bool immediate = false)
    {
        Component component = obj.GetComponent<Component>();

        if (component != null)
        {
            if (immediate)
            {
                Object.DestroyImmediate(component as Object, true);
            }
            else
            {
                Object.Destroy(component as Object);
            }

        }
    }

    public static void ResetTransformation(this Transform trans)
    {
        trans.position = Vector3.zero;
        trans.localRotation = Quaternion.identity;
        trans.localScale = new Vector3(1, 1, 1);
    }
}
Fredrik Schön
  • 4,888
  • 1
  • 21
  • 32