public static ulong OnResourceWrite(IntPtr pathHandler, IntPtr data, ulong offset, ulong size)
    {
        if (data == IntPtr.Zero)
        {
            return(0);
        }
        string path = Marshal.PtrToStringAnsi(pathHandler);

        if (!Application.isPlaying)
        {
#if UNITY_EDITOR
            string unityPackFx = Path.Combine("Assets/", PKFxSettings.UnityPackFxPath);
            string finalPath   = Path.Combine(unityPackFx, path);

            string dir = Path.GetDirectoryName(finalPath);
            Directory.CreateDirectory(dir);

            FileStream   fs           = new FileStream(finalPath, FileMode.Create);
            BinaryWriter bw           = new BinaryWriter(fs);
            byte[]       managedArray = new byte[size];

            Marshal.Copy(data, managedArray, 0, (int)size);
            bw.Write(managedArray);

            bw.Close();
            fs.Close();

            UnityEditor.AssetDatabase.Refresh();

            Debug.Log("[PKFX] Wrote asset to PackFx : " + path);
            return(size);
#endif
        }
        else
        {
            Debug.Assert(m_IsStarted == true);
            GameObject           go      = new GameObject();
            PKFxRuntimeMeshAsset newMesh = go.AddComponent <PKFxRuntimeMeshAsset>();
            newMesh.m_AssetName = path;
            go.name             = path;
            newMesh.m_Data      = new byte[size];
            Marshal.Copy(data, newMesh.m_Data, 0, (int)size);
            if (m_RuntimeAssetsRoot == null)
            {
                m_RuntimeAssetsRoot = new GameObject("PopcornFX Runtime Assets");
                m_RuntimeAssetsRoot.transform.position = Vector3.zero;
                m_RuntimeAssetsRoot.isStatic           = true;
                UnityEngine.Object.DontDestroyOnLoad(m_RuntimeAssetsRoot);
            }
            go.transform.parent = m_RuntimeAssetsRoot.transform;
            m_RuntimeAssets.Add(go);
            return(size);
        }
#if !UNITY_EDITOR
        return(0);
#endif
    }
    public static ulong OnResourceLoad(IntPtr pathHandler, ref IntPtr handler)
    {
        string path  = Marshal.PtrToStringAnsi(pathHandler);
        string fName = Path.GetFileName(path);
        string ext   = Path.GetExtension(path);

        if (m_Dependencies != null)
        {
            if (arrayContains(s_CustomFileTypes, ext))
            {
                foreach (PKFxAsset asset in m_Dependencies)
                {
                    if (Path.GetFileName(asset.m_AssetName) == fName)
                    {
                        var pinned = PinAssetData(asset);
                        handler = pinned;
                        return((ulong)asset.m_Data.Length);
                    }
                }
            }
            else if (arrayContains(s_TexFileTypes, ext))
            {
                foreach (var t in m_TexDependencies)
                {
                    if (t.name == Path.GetFileNameWithoutExtension(fName))
                    {
                        ulong len = PinTextureData(t, ref handler);
                        return(len);
                    }
                }
            }
        }
        if (m_RuntimeAssets != null && m_RuntimeAssets.Count > 0)
        {
            // failing that, check if we have it in the runtime resources
            foreach (GameObject go in m_RuntimeAssets)
            {
                PKFxRuntimeMeshAsset asset = go.GetComponent <PKFxRuntimeMeshAsset>();
                if (Path.GetFileName(asset.m_AssetName) == fName)
                {
                    var pinned = PinAssetData(asset);
                    handler = pinned;
                    return((ulong)asset.m_Data.Length);
                }
            }
        }
        Debug.LogError("[PKFX] " + fName + " not found in dependencies.");
        return(0);
    }