I know this is probably a nooby question but I can’t figure out how to simply copy an instance of a component or how to attach/reattach component instances to different game objects. Everything I find online is either editor only or involves reflection which I’d like to avoid if i can for performance.
I thought AddComponent would take component instances as an argument like instantiate(gameobject) does but it doesnt seem to have that…
What’s the intended unity way of copying and moving components?
There simply is no way at the moment. Component instances are tied to their housing gameobject. Components can not be detached and attached to other gameobjects at all. So your only solution is to create the same component on your target gameobject and copy all values over and destroy the old one. When the component itself provides this functionality, you don’t need reflection. However if you want to support any kind of component, reflection is the only real solution at the moment.
Though keep in mind that even reflection has its limits. All build-in components are actually implemented in native C++ code and you only have a managed wrapper class with properties that map to native methods. So those components do not have managed fields that could be copied, only properties.
You can copy whole gameobjects including its components but not individual components on their own. Think of it like you’re being able to clone a human but you can not detach an arm of one human and stitch it onto another. This would require more advanced surgery.
Technically every component has a managed and a native part. In case of monobehaviours the native part of the component if of course always the same C++ class and the actual behaviour of the class is implemented in Mono / .NET (hence the name since from the engine’s perspective it’s a behaviour that is delegated to the managed side). Theoretically it should be possible to detach components and move them to other gameobjects. However this could have countless of issues when you think about the Start method. If you suddenly change the host gameobject, all references gathered in Start would be pointing to the old hosting gameobject. That’s why Unity does not even support such an action.
Technically on the native side a MonoBehaviour component and a ScriptableObject are the same thing, just that a ScriptableObject is not attached to a gameobject. Both MonoBehaviour and ScriptableObject are represented in native code by the same class. At least that got confirmed by Richard Fine in his ScriptableObject talk (there are actually two versions, here’s the other with basically the same content.).