PropertyInfo.SetValue() error while trying to copy animation rigging constraints

Hi,

I’ve been working on a development tool for copying animation rigging constraints from one empty to another, finding components that inherit from IRigConstraint. It doesn’t print any errors and adds the component, but PropertyInfo.SetValue() isn’t actually changing the data of the component for some reason. I don’t know if this is an issue with the animation rigging package since it is in early release, or if I’m doing something wrong. This code reproduces the effect:

    public void CopyConstraint (GameObject target)
    {
        GameObject bone = transform.gameObject;
        IRigConstraint copyFrom = target.GetComponent<IRigConstraint>();
        if (copyFrom != null)
        {
            IRigConstraint copyTo = (IRigConstraint)bone.AddComponent(copyFrom.GetType());
            PropertyInfo[] properties = copyTo.data.GetType().GetProperties();
            foreach (PropertyInfo pi in properties)
            {
                var data = pi.GetValue(copyFrom.data);
                pi.SetValue(copyTo.data, data);
            }
        }
    }

Right now this function just runs from a button pressed in a custom inspector.

Am I doing something wrong here? Is this an error with the preview package and, if so, is there a workaround? It needs to work for all constraint types and, ideally, for custom constraints as well so I want to keep it as general as possible

Thanks in advance,
Adam

Ok so to give an update on this, it seems the issue is with boxing/unboxing in c#. I don’t entirely understand it but it seems like in order for SetValue to work the variable needs to be “boxed” into an object, and then “unboxed” when it’s done? So the correct way of doing this would be to with the following, slightly different code:

    public void CopyConstraint (GameObject target)
    {
        GameObject bone = transform.gameObject;
        IRigConstraint copyFrom = target.GetComponent<IRigConstraint>();
        if (copyFrom != null)
        {
            IRigConstraint copyTo = (IRigConstraint)bone.AddComponent(copyFrom.GetType());
            PropertyInfo[] properties = copyTo.data.GetType().GetProperties();
            object dataObj = copyTo.data; //"Boxing" copyTo.data
            foreach (PropertyInfo pi in properties)
            {
                var data = pi.GetValue(copyFrom.data);
                pi.SetValue(dataObj, data);
            }
            copyTo.data = dataObj as IAnimationJobData // "Unboxing" copyTo.data
        }
    }

The issue with this is that it tells me copyTo.data is a read-only property. Am I doing this wrong? Or is this just a scripting limitation with Unity - and if so is there a workaround?

Thanks,
Adam