Array.Copy trouble

Array.Copy (in C#) does not seem to be working for some reason. I have a simplified test:

Debug.Log("before: " + particles[0].position + " != " + emitters[0].particles[0].position);

for (int e = 0; e < emitters.Length; e++)
{
    System.Array.Copy(particles, 0, emitters[0].particles, 0, 1);
}

Debug.Log("after: " + particles[0].position + " == " + emitters[0].particles[0].position);

The output is:

before: (1.3, 0.9, -3.0) != (0.1, 0.5, 0.3)
after: (1.3, 0.9, -3.0) == (0.1, 0.5, 0.3)

Any ideas?

MY SOLUTION:

You should never use the Array class for game development… it’s far too inefficient.

Instead, try using a standard array or a List object.

I have not seen Array.Copy before (in JS), so I assume it is a C# variant?

Normally (in JS) if you were copying re-iteratively, you would use Arr.Add().

Otherwise just assign arr1 = arr2;

I assume this is done differently in C#?

– Peter

He’s not. System.Array.Copy is for built-in .NET arrays, it doesn’t work with the Array class.

Neither, it’s Mono (.NET).

That doesn’t copy an array, it merely makes a reference.

C# and JS (and Boo) all use Mono, so no, it’s not done differently.

I’m not sure what this loop is doing, since it’s using emitters[0] for every iteration. You mean “emitters[e]”? Edit: also, I think you can’t assign individual elements to ParticleEmitter.particles. It’s probably the same as e.g. Mesh.vertices, where you have to assign the entire array at once, you can’t write to individual items directly.

–Eric

Thanks for the replies guys. Sorry, I should have explained the context. I am using C#. I want to create one large array of particles that contains multiple sets of ParticleEmitter particle arrays, in order to overcome the mesh size limit of 16,250 particles.

First I tried built-in arrays since that’s the best choice, but I couldn’t figure out a built-in way to copy just a subset of the array. So then I tried ArrayList, but I had trouble in one spot trying to cast to Particle, so I gave up on it. Then I tried a List<>, which worked just fine, but it’s a little too slow at 20-25 fps in-editor. Then I found out about Array.Copy, and now I am at Arrays.

Yes, I was originally doing emitters[e], emitters is an array of ParticleEmitter objects. emitters[0].particles is the first ParticleEmitter element, and it is valid to assign an array to its particles, which I was originally trying to do.

But you might have something there, maybe somehow my count is off and I’m not actually assigning every particle? Here’s the real code:

void AssignParticles ()
{
	////////
	// assign particles back
	////////
	Debug.Log("before: " + particles[0].position + " != " + emitters[0].particles[0].position);
	for (int e = 0; e < emitters.Length; e++)
	{
		System.Array.Copy(particles, particleIndices[e], emitters[e].particles, 0, emitters[e].particles.Length);
	}
	Debug.Log("after: " + particles[0].position + " == " + emitters[0].particles[0].position);
}

Right now there are two emitters in the array, both maxed out at 16,250 particles. particleIndices[0] is 0, and 1 is 16250. I figured at least the first one would work…

Debug.Log("copying " + emitters[e].particles.Length + " particles at " + particleIndices[e]);

spits out:

copying 16250 particles at 0
copying 16250 particles at 16250

It looks like particleEmitter.particles does not like to be copied into by Array.Copy. I created a temporary variable and assigned that to it, and it worked:
http://img713.imageshack.us/img713/9029/weivstrangeattractor.png

Not sure if this is a bug or a “feature.” :stuck_out_tongue:

I like the png :slight_smile:

It is unclear to me why you need to place them in a single place. You could reference to each ParticleEmitter separately, but perhaps I do not fully understand your intentions.
If it is necessary to place them together, could a structure help ? http://msdn.microsoft.com/en-us/library/aa288471(v=vs.71).aspx

Thanks! This is a strange attractor calculation. I want to separate the attractors from the particle systems so that I can support multiple systems.

In fact, at first I did keep them separate. But for some reason, when I tried to attach my script to each particle system and have them reference the attractors, I could only get one of the systems to reference the attractors correctly. Frustrated, I decided to have a completely separate manager-style object, and then reference the attractors and the particle emitters. And since I was doing that, I started with an array of arrays, but that wasn’t working very well, so I moved to putting everything all in one.

Eventually, I’d like to have the positions and velocities in a texture using a pixel shader, which means one array. Some day…

Ok, a thought :
Say you have an equation (function) that you want to apply over 3 particle emitters with 10 particles each.

  1. Apply the equation to all the particles of the particle emitter 1
  2. Set the first particle [0] of particle emitter 2 to have the same state as the last particle [10] of particle emitter 1 (*)
  3. Apply the equation on the particle emitter 2
    etc
    Could this work for you in the complex example you try to make ?

(*)The same state ie particleFromParticleEmitter1 [10] = particleFromParticleEmitter2 [0], maybe I use wrong term :slight_smile:

My system is completely deterministic, so really I only need to do #1 and #3. The particles don’t know or care about each other, they just move according to the gravity of the attractors.

And I’m only using multiple emitters because I maxed out the first one at 16,250 particles. Otherwise I’d just use one emitter with 30 particles.

The equation is basically this pseudocode:

distance = attractorPos - particlePos
acceleration = power * distance / distance.sqrMagnitude
velocity += acceleration
nextParticlePos += velocity
velocity *= dampening

particlePos = nextParticlePos

As you can see, the next position is only based on the existing position. So if the particle ends up in that same position again, it’s a loop.

Another thought :slight_smile:
Could you “bake” the particle’s movements in an animation ? That could save some cycles.

Sadly no, baking is out because I want the particles to be fully dynamic, since now I have the ability to move the attractors around in real-time. Although if I was really good at math (I’m not), I could find a way to shortcut the calculation, sort of like how noise optimizations work. Honestly though, the calculation itself isn’t that bad.

Your question did prompt me to use the profiler, and in doing so I found that I was looking up the attractor GameObject position for every particle for every attractor, which is quite expensive. So I just store the positions as Vector3s in an array and grab that, which is much faster.

So now I’m back up to 60fps in-editor with two maxed emitters and 5 attractors. Thanks for the motivation :slight_smile: