复制组件的正确方法是什么?

What is the correct way to copy a component?

这个问题我想了很久,因为复制它的过程似乎没有那么难。虽然Unity可以用instantiate的代码轻松复制无数个组件,但为什么我在单个组件中看不到这样的功能?

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

如您所见,它并没有改变任何东西。有趣的是,Rider IDE 也显示它在带有黄色下划线的代码中无效。


最佳解决方案是什么?

考虑到变量到变量的复制是一种初学者方式,我正在寻找一种可以使用 Generic 方法复制任何组件的解决方案。接受任何帮助。

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

secondFly = _fly; 告诉计算机“从现在开始,如果我说 secondFly,我指的是执行此行时 _fly 引用的组件(对象)。 " 它不会修改变量 secondFly 引用的组件,它只会更改 secondFly 引用的内容。这是因为 secondFly 是一个对象(声明为 public class ClassName {...}Component, Rigidbody, etc 的任何类型),而不是基本类型 (int, float, double, byte, etc.)。对象类型的变量本身不是数据,它们指向 to/reference 数据。


初学者之路

你可以像这样复制_fly的变量:

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

进阶方式

由于 Unity 的组件工作方式,我认为没有简单的方法可以复制组件并将其附加到游戏对象,但如果您不想手动复制组件的变量,请尝试将此函数添加到您的代码中并调用它来复制您的组件(来自 https://answers.unity.com/questions/458207/copy-a-component-at-runtime.html

public static T CopyComponent<T>(T original, GameObject destination) where T : Component
{
    var type = original.GetType();
    var copy = destination.AddComponent(type);
    var fields = type.GetFields();
    foreach (var field in fields) field.SetValue(copy, field.GetValue(original));
    return copy as T;
}