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.
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;
}