How can I serialize the Particles of a Particle Emitter

I want to save the array of Particles returned by the particles property so that I can load it at a later time. How can I do this?

You can use .net marshalling to save the array of particles (structs). First you need to convert the array to a byte, then save it as a binary file. To load you would read each particle, and convert from byte to a Particle struct.

Create a CSharp script named SerializeParticles .cs. Copy/paste the following code:

using UnityEngine;
public class SerializeParticles : MonoBehaviour
{
}

You need to attach the previous script to the GameObjec with the particle emitter component.

Create another CSharp script named CustomInspectorParticles.cs and place it inside an Editor folder. Copy/paste the following code:

using System.IO;
using UnityEngine;
using UnityEditor;
using System;
using System.Runtime.InteropServices;

[CustomEditor(typeof(SerializeParticles))]
public class CustomInspectorParticles : Editor
{
    public override void OnInspectorGUI()
    {
        var t = target as SerializeParticles;
        if (t != null){
            if (GUILayout.Button("Load Particle Data"))
                t.gameObject.GetComponent<ParticleEmitter>().particles = LoadParticleData();

            if (GUILayout.Button("Save Particle Data"))
                SaveParticleData(t.gameObject.GetComponent<ParticleEmitter>().particles);
        }

        if (GUI.changed)
            EditorUtility.SetDirty(target);
    }

    static Particle[] LoadParticleData()
    {
        // Load the byte array
        var fs = new FileStream(Application.dataPath + "/particleData.asset", FileMode.Open, FileAccess.Read, FileShare.None);

        // Number of particles
        var dataSize = Marshal.SizeOf(new Particle());
        var numParticles = ((int)fs.Length / dataSize);
        var particles = new Particle[numParticles];

        // Create a byte[] to hold all the particle data
        var byteArray = new byte[dataSize];
        var pointer = Marshal.AllocHGlobal(dataSize);
        try {
            for (var i = 0; i < numParticles; i++) {
                // Read the bytes of a particle
                fs.Read(byteArray, 0, dataSize);
                // Copy the byteArray to unmanaged memory
                Marshal.Copy(byteArray, 0, pointer, dataSize);
                // Particle in unmanaged memory 
                particles *= (Particle)Marshal.PtrToStructure(pointer, typeof(Particle));*

}
}
finally {
// Free the unmanaged memory.
Marshal.FreeHGlobal(pointer);
}
fs.Close();

return particles;
}

static void SaveParticleData(Particle[] particles)
{
if (particles == null)
return;
if (particles.Length == 0)
return;

// Size of the entire array
int totalSize = Marshal.SizeOf(new Particle()) * particles.Length;
int dataSize = Marshal.SizeOf(new Particle());

// Create a byte[] to hold all the particles, but only one can be copied at the time
var byteArray = new byte[totalSize];
IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf(new Particle()));
try {
for (var i = 0; i < particles.Length; i++) {
Marshal.StructureToPtr(particles*, pointer, false);*
Marshal.Copy(pointer, byteArray, i * dataSize, dataSize);
}
}
finally {
// Free the unmanaged memory.
Marshal.FreeHGlobal(pointer);
}

// Save the byte array
var fs = new FileStream(Application.dataPath + “/particleData.asset”, FileMode.Create, FileAccess.Write, FileShare.None);

// Save the particle data
fs.Write(byteArray, 0, byteArray.Length);
fs.Close();
}
}
[Note: This code is a guideline, it needs more data validation]