Home > Blockchain >  What is the correct way to copy a component?
What is the correct way to copy a component?

Time:05-18

This question has been on my mind for a long time because the process of copying it does not seem so difficult. Although Unity can easily copy countless components with instantiate code, why do not I see such a feature in a single component?

public class FreeFly : MonoBehaviour
{
    public float wingSpeed = 2f;
    public bool canFly = true;
    
    public void CopyComponent()
    {
        wingSpeed = 10f;
        canFly = false;
        
        var _fly = this;
        var secondFly = gameObject.AddComponent<FreeFly>(); 
        
        secondFly = _fly; // The second component did not register the changes.
    }

    public void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) CopyComponent();
    }
}

As you can see, it does not change anything. Interestingly, the Rider IDE also shows it ineffective in code with a yellow underscore.

enter image description here


What is the best solution?

Considering that variable-to-variable copy is a beginner way, I am looking for a solution that can copy any component using the Generic method. Any help is accepted.

public T CopyComponent<T>(T copyFrom)
{
    // I want this one..
    
    return copyFrom;
}

CodePudding user response:

secondFly = _fly; tells the computer "from now on, if I say secondFly, I mean the Component (Object) that _fly referenced at time of executing this line." It does not modify the component that was referenced by the variable secondFly, it only changes what secondFly refers to. This is because secondFly is an Object (any type declared as public class ClassName {...}, Component, Rigidbody, etc), not a primitive type (int, float, double, byte, etc.). Variables that are of Object types aren't data themselves, they point to/reference data.

"Beginner Way": You can copy the variables of _fly

secondFly.wingSpeed = _fly.wingSpeed;
secondFly.canFly = _fly.canFly;

"Advanced Way": Because of the way Unity's Components work, I don't think there's a simple way to duplicate a Component and attach it to a GameObject, but if you don't want to manually copy the variables of the Component, try adding this function to your code and calling it to duplicate your Component (from https://answers.unity.com/questions/458207/copy-a-component-at-runtime.html)

T CopyComponent<T>(T original, GameObject destination) where T : Component
 {
     System.Type type = original.GetType();
     Component copy = destination.AddComponent(type);
     System.Reflection.FieldInfo[] fields = type.GetFields();
     foreach (System.Reflection.FieldInfo field in fields)
     {
         field.SetValue(copy, field.GetValue(original));
     }
     return copy as T;
 }
  • Related