// This is a positional argument
    public Rig3DAssetAttribute(string name, Rig3DExports exports = 0)
    {
        Name = name;
        Exports = exports;

        // TODO: Implement code here
        //throw new NotImplementedException();
    }
 private static bool ExportContainsProperty(Rig3DExports defaultExports, Rig3DExports exports)
 {
     return (defaultExports & exports) == exports;
 }
    private static JArray GetAssetArray(Type assetType, Rig3DExports defaultExports)
    {
        var objs = Object.FindObjectsOfType(assetType).Cast<MonoBehaviour>();

        var fields = GetExportFields(assetType);
        var properties = GetExportProperties(assetType);

        var array = new JArray();
        foreach (var behaviour in objs)
        {
            var jobj = CreateJsonObject(behaviour, defaultExports);

            foreach (var fieldPair in fields)
            {
                var name = fieldPair.Value.Name;
                if (string.IsNullOrEmpty(name))
                {
                    name = fieldPair.Key.Name;
                }

                var value = fieldPair.Key.GetValue(behaviour);
                if(value is Vector3)
                {
                    jobj.Add(name, ToJToken((Vector3)value));
                }
                else
                {
                    jobj.Add(name, new JValue(value));
                }
            }

            foreach (var propPair in properties)
            {
                var name = propPair.Value.Name;
                if (string.IsNullOrEmpty(name))
                {
                    name = propPair.Key.Name;
                }

                var value = propPair.Key.GetValue(behaviour, null);
                if (value is Bounds)
                {
                    jobj.Add(name, ToJToken((Bounds)value));
                }
                else
                {
                    jobj.Add(name, new JValue(value));
                }
            }

            array.Add(jobj);
        }
        return array;
    }
    private static JObject CreateJsonObject(Component component, Rig3DExports defaultExports, bool normalizeDepth = false)
    {
        var jobj = new JObject();

        var transform = component.transform;
        if (ExportContainsProperty(defaultExports, Rig3DExports.Position))
        {
            var pos = transform.position;
            if (normalizeDepth)
            {
                pos.z = 0;
            }
            jobj.Add("position", ToJToken(pos));
        }

        if (ExportContainsProperty(defaultExports, Rig3DExports.Rotation))
        {
            jobj.Add("rotation", ToJToken(transform.rotation));
        }

        if (ExportContainsProperty(defaultExports, Rig3DExports.Scale))
        {
            var skl = transform.lossyScale;
            if (normalizeDepth)
            {
                skl.z = 1;
            }
            jobj.Add("scale", ToJToken(skl));
        }

        if (ExportContainsProperty(defaultExports, Rig3DExports.Layer))
        {
            jobj.Add("layer", transform.gameObject.layer);
        }

        if (ExportContainsProperty(defaultExports, Rig3DExports.Tag))
        {
            jobj.Add("tag", transform.gameObject.tag);
        }

        if (ExportContainsProperty(defaultExports, Rig3DExports.Mesh))
        {
            var mesh = transform.GetComponentInChildren<MeshFilter>();
            if (mesh)
            {
                var meshtrans = mesh.transform;
                Bounds bounds = new Bounds(meshtrans.TransformPoint(mesh.sharedMesh.bounds.min), Vector3.zero);
                bounds.Encapsulate(meshtrans.TransformPoint(mesh.sharedMesh.bounds.max));
                jobj.Add("bounds", ToJToken(bounds));
            }
        }

        return jobj;
    }