Как правильно скопировать компонент?

Этот вопрос давно не дает мне покоя, потому что процесс копирования не кажется таким уж сложным. Хотя 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();
    }
}

Как видите, это ничего не меняет. Интересно, что Райдер IDE также показывает его неэффективность в коде с желтым подчеркиванием.

Как правильно скопировать компонент?


Какое лучшее решение?

Учитывая, что копирование переменной в переменную — это способ для начинающих, я ищу решение, которое может копировать любой компонент с помощью метода Generic. Любая помощь принимается.

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

🤔 А знаете ли вы, что...
C# поддерживает событийно-ориентированное программирование с помощью ключевых слов event и delegate.


20
1

Ответ:

Решено

secondFly = _fly; сообщает компьютеру «с этого момента, если я говорю secondFly, я имею в виду Компонент (Объект), на который ссылается _fly во время выполнения этой строки.». Он не изменяет компонент, на который ссылается переменная secondFly, он изменяет только то, на что ссылается secondFly. Это связано с тем, что secondFly — это объект (любой тип, объявленный как public class ClassName {...}, Component, Rigidbody, etc), а не примитивный тип (int, float, double, byte, etc.). Переменные типа Object сами по себе не являются данными, они указывают/ссылаются на данные.

«Путь для начинающих»: вы можете скопировать переменные _fly

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

«Продвинутый способ»: Из-за того, как работают компоненты Unity, я не думаю, что есть простой способ дублировать компонент и прикрепить его к игровому объекту, но если вы не хотите вручную копировать переменные компонента, попробуйте добавить эту функцию в свой код и вызвать его для дублирования вашего компонента (из 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;
 }