Unity particle array and DLL. How to access? [SOLVED]

Hi,

There is there a way to access an array of particle from a dll (plugin)?
Thx

JP

There are no structures in Unity that can be accessed directly from plugin code, but you can pass most data in from a script. There is some information about this here in the manual.

I can not believe it is impossible to access the table «particles» from a dll. Unity3d not so close as that. Yes? :frowning:
This is important. It’s for my wip project : http://forum.unity3d.com/viewtopic.php?t=46371
JP

From the Procedural exemple code

/*
	This script is placed in public domain. The author takes no responsibility for any possible harm.
	Contributed by Jonathan Czeck
*/
using UnityEngine;
using System.Collections;

public class LightningBolt : MonoBehaviour
{
	public Transform target;
	public int zigs = 100;
	public float speed = 1f;
	public float scale = 1f;
	public Light startLight;
	public Light endLight;
	
	Perlin noise;
	float oneOverZigs;
	
	private Particle[] particles;
	
	void Start()
	{
		oneOverZigs = 1f / (float)zigs;
		particleEmitter.emit = false;

		particleEmitter.Emit(zigs);
		particles = particleEmitter.particles;
	}
	
	void Update ()
	{
		if (noise == null)
			noise = new Perlin();
			
		float timex = Time.time * speed * 0.1365143f;
		float timey = Time.time * speed * 1.21688f;
		float timez = Time.time * speed * 2.5564f;
		
		for (int i=0; i < particles.Length; i++)
		{
			Vector3 position = Vector3.Lerp(transform.position, target.position, oneOverZigs * (float)i);
			Vector3 offset = new Vector3(noise.Noise(timex + position.x, timex + position.y, timex + position.z),
										noise.Noise(timey + position.x, timey + position.y, timey + position.z),
										noise.Noise(timez + position.x, timez + position.y, timez + position.z));
			position += (offset * scale * ((float)i * oneOverZigs));
			
			particles[i].position = position;
			particles[i].color = Color.white;
			particles[i].energy = 1f;
		}
		
		particleEmitter.particles = particles;
		
		if (particleEmitter.particleCount >= 2)
		{
			if (startLight)
				startLight.transform.position = particles[0].position;
			if (endLight)
				endLight.transform.position = particles[particles.Length - 1].position;
		}
	}	
}

Unity doesn’t have any API for C/C++. Plugin code can’t therefore access anything in the scene directly. However, a Unity script can pass data to functions in the plugin as described on the manual page I linked in my previous post.

Oohh!! I missed the most important line : " particleEmitter.particles = particles;"
Thx 8)

JP

Hi,

THIS is the solution. Have fun 8)

// C source ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// this is defined when compiling with Visual Studio 
#define EXPORT_API __declspec(dllexport) // Visual Studio needs annotating exported functions with this 
#include <math.h> 
// ------------------------------------------------------------------------ 
// Plugin itself 
// Link following functions C-style (required for plugins) 
extern "C" 
{ 
 
// The function we will call from Unity. 
// 
// We pass the Particle array, Particle number
void EXPORT_API UpdateParticle( void* particle, int number ) 
{ 
	float* data = reinterpret_cast<float*>(particle); 
	
	for (int x=0; x<number + 1; x++)
	{ 
		float* tab = (data + x) * 12; // 

		tab[0] = rand() % 100 + 1; //  Particle X position
		tab[1] = rand() % 100 + 1; //  Y position
		tab[2] = rand() % 100 + 1; //  Z position
		tab[3] = 1; //  Velocity X 
		tab[4] = 1; //  Vy
		tab[5] = 1; //  Vz
		tab[6] = 1; //  Energy
		tab[7] = 1; //  Size
		tab[8] = 1; //  color Red
		tab[9] = 1; //  Green
		tab[10] = 1; //  Blue
		tab[11] = 1; //  Alpha
	} 
} 
} // end of export C block 
// C source ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
PartTest.cs

 // Particle DLL test ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;

public class PartTest : MonoBehaviour 
{
	[DllImport ("DLL_name.dll", EntryPoint="_UpdateParticle@8")]
	private static extern void UpdateParticle(IntPtr ParticleArray, int nbrPart);
   
	private Particle[] particles;
	private int number = 500;
    private GCHandle ParticleHandle; 
 
    void Start ()
	{
		particleEmitter.emit = false;
		particleEmitter.Emit(number);
		particles = particleEmitter.particles;
        ParticleHandle = GCHandle.Alloc(particles, GCHandleType.Pinned); 
	}

    void Update ()
	{
		// the particles are moved by the Dll. cool !!!!
        UpdateParticle (ParticleHandle.AddrOfPinnedObject(), number); 
		particleEmitter.particles = particles;
	}
    void OnDisable()
	{ 
        // Free the pinned array handle. 
        ParticleHandle.Free(); 
    } 
 }
// Particle DLL test ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Hi,

First of all, the order listed in this page ( http://unity3d.com/support/documentation/ScriptReference/Particle.html) is not good. It must be reversed “energy” and “size” for access by a Dll.

  • You need a “Ellipsoid Particle Emitter” and a “Particle Renderer” (Only 8) )
  • Here a FreeBasic version of the DLL.

JP

Declare Sub UpdateParticle Lib "LIB_NAME"  ( ByVal ParticleArray As UInteger Ptr,ByVal nbrPart As UInteger  )

Sub UpdateParticle ( ByVal ParticleArray As UInteger Ptr, ByVal nbrPart As UInteger ) Export
	Dim i As UInteger 
	Dim dep As UInteger
	For i=0 To nbrPart
		dep =  ParticleArray + i  * 12
		Poke Single, dep + 0 , Rnd * 100
		Poke Single, dep + 4 , Rnd * 100
		Poke Single, dep + 8 , Rnd * 100
	'	Poke Single, dep + 12, 0 ' Vx
	'	Poke Single, dep + 16, 0 ' Vy
	'	Poke Single, dep + 20, 0 ' Vz

		Poke Single, dep + 24,Rnd*5 ' size !!!!
		Poke Single, dep + 28,1 ' Energy !!!!
		
		Poke Single, dep + 32,Rnd*1 ' Red
		Poke Single, dep + 36,Rnd*1 ' Green
		Poke Single, dep + 40,Rnd*1 ' Blue
		Poke Single, dep + 44,1 ' Alpha
	Next

End Sub