Changing the appearance of particles from another player's view

Okay so I've pretty much edited the entire question but it's still the exact same question. Currently we have a 4 person multiplayer game that works over a network. We use a particle emitter as a firing mechanism, each player has their own particle emitter but they all use the same "Fire" script.

How do we set the appearance of a players particles over the network. This includes force properties, shaders & textures and even states (eg flamethrower or normal shot) Should I just make 4 scripts one for each fire (which is what we resorted to for the player and everything works perfectly no torubles now) or is there a way to send a player's emitter state via RPC without it taking too much bandwidth sending every single variable?

We have a set up so that player one is the host who launches/runs the server. We have a pickup that activates the FLAMETHROWER and that works fine, locally. Each player can see the pickup and collect the pickup. When the player has collected the pickup it only shows on their machine. Everyone else registers the fact that a certain player has picked it up but still the particles remain the same. What we are looking for is a way to set what the particles are doing locally then send it over the network so that each player can see exactly how far your firing and whether or not your have a flamethrower etc (we also have aiming which increases the particles local velocity which needs to be synced)

This is what we have so far. The part in which we set emitter on and off over the network works fine however the RPC call "SwitchFire" doesn't work at all.Mainly because the variable we are setting doesn't do anything, just demonstrating the fact we have had several attempts (and failed each time, this just causes no problems)

private var wasEmitting : boolean = false;
static var Ammo1 : float = 100;
var AmmoRep : float = 100;
static var AmmoUnlimited : boolean = false;
var AuTime : float = 10;
var Ammo1full : float = 100;
var CanFire : boolean = true;
var SpoutPos : Vector3 = new Vector3(-0.05,0.7,0.45);
static var Aimvar : Vector3 = new Vector3(0,5,5);
var bforce : Vector3 = new Vector3(0,-50,0);
var isFlameThrower : boolean = false;
var wasFlameThrower : boolean = false;
static var FLAMETHROWER : boolean = false;
var flameon : boolean = false;
var hasfilled : boolean = false;
var flamethrowerPos : Vector3 = new Vector3(0,0.35,0.05);
var flameLife : float = 0.5;
var flameAmount : float = 200;
var flameVel : Vector3 = new Vector3(0,0,5);
var flameSize : Vector3 = new Vector3(1,1,1);
var forceOverTime : Vector3 = new Vector3(0,0,0);
var flameSpeed : float = 0.5;
var Fire : Texture;
var Flame : Shader = Shader.Find( "Particles/Additive (Soft)" );
var Tea : Texture;
var regShad : Shader = Shader.Find( "Transparent/Diffuse" );

function Update ()
{
    AmmoRep = Ammo1;
    if (networkView.isMine)
    {
        if (FLAMETHROWER == true)
        {
            flameon = true;
            networkView.RPC("SwitchFire", RPCMode.Others, flameon);
            QuickFill();
            transform.localPosition = flamethrowerPos;          
            renderer.material.mainTexture = Fire;
            renderer.material.shader = Flame;
            particleEmitter.minEnergy = flameLife;
            particleEmitter.maxEnergy = flameLife;
            particleEmitter.minEmission = flameAmount;
            particleEmitter.maxEmission = flameAmount;                  
            particleEmitter.localVelocity = flameVel;
            particleEmitter.rndVelocity = flameSize;
            blah = GetComponent (ParticleAnimator);
            blah.force = forceOverTime;
            blah.damping = flameSpeed;

            if(Input.GetButton("Fire"))
            {
                particleEmitter.emit = true;
                Ammo1 = Ammo1 - 9*Time.deltaTime;               
                if (Ammo1 <= 0)
                {
                    FLAMETHROWER = false;
                    hasfilled = false;
                    CanFire = true;
                    networkView.RPC("SetIsOut", RPCMode.Others, particleEmitter.emit);
                    wasEmitting = particleEmitter.emit;
                    Refill();
                }
            }
            else
            {
                particleEmitter.emit = false;               
            }
        }
        if (FLAMETHROWER == false)
        {   
            flameon = false;
            networkView.RPC("SwitchFire", RPCMode.Others, flameon);
            hasfilled = false;
            transform.localPosition = SpoutPos;
            renderer.material.mainTexture = Tea;
            renderer.material.shader = regShad;
            particleEmitter.minEnergy = 1.5;
            particleEmitter.maxEnergy = 1.5;
            particleEmitter.minEmission = 25;
            particleEmitter.maxEmission = 25;
            particleEmitter.localVelocity = Aimvar;
            particleEmitter.rndVelocity = Vector3(0.2,0.2,0.04);
            blah = GetComponent (ParticleAnimator);
            blah.force = bforce; 
            blah.damping = 10;

            if (AmmoUnlimited == true)
            {
                Refill();
                CanFire = true;
                UnlimitedAmmoCountDown();
            }

            if (CanFire == true)
            {
                if(Input.GetButton("Fire"))
                {
                    particleEmitter.emit = true;
                    if (AmmoUnlimited == false)
                    {
                        Ammo1 = Ammo1 - 9*Time.deltaTime;
                    }
                    if (Ammo1 <= 0)
                    {
                        CanFire = false;
                        networkView.RPC("SetIsOut", RPCMode.Others, particleEmitter.emit);
                        wasEmitting = particleEmitter.emit;
                    }
                }
                else
                {
                    particleEmitter.emit = false;
                    if (Ammo1 <= Ammo1full)
                    {
                        Ammo1 = Ammo1 + 11*Time.deltaTime;
                    }
                }

            }
        }
        if (CanFire == false)
        {
            particleEmitter.emit = false;
            Ammo1 = Ammo1 + 8*Time.deltaTime;
            if (Ammo1 >= Ammo1full)
            {
                CanFire = true;
            }
        }
        if(particleEmitter.emit != wasEmitting)
        {
            networkView.RPC("SetIsFiring", RPCMode.Others, particleEmitter.emit);
            wasEmitting = particleEmitter.emit;
        }
    }
}

function QuickFill()
{
    if (hasfilled == false)
    {
        Ammo1 = 100;
        hasfilled = true;
    }
}

function Refill()
{
    Ammo1 = 100;
    Debug.Log ("Refill function activated");
}

function Reloading ()
{
    CanFire = false;
    if (Ammo1 >= Ammo1full)
    {
        CanFire = true;
    }
}

function UnlimitedAmmoCountDown()
{
    yield WaitForSeconds (AuTime);
    AmmoUnlimited = false;
}

@RPC
function SetIsFiring(boolEmitting : boolean)
{
    particleEmitter.emit = boolEmitting;    
}

@RPC
function SetIsOut(boolEmitting : boolean)
{
    particleEmitter.emit = false;   
}

@RPC
function SwitchFire (flamebool : boolean)
{
    flameon = flamebool;
    Debug.Log ("recieved fire RPC");
}

Have you tried spliting it into four different scripts and have each script sending an rpc to set how it acts on other player's local machine?

I'm guessing you're stuck on "how do I send a particle emmiter through an RPC?" Turns out you are only allowed to send ints, floats, transforms (which are just 9 floats...,) strings, but not larger objects.

You could number the potential emitters (or put them in an array) and do something like:

// pickup code:
// someone figures out new emmiter num
SetEmmiter(newEmitNum); // set for me
networkView.RPC("SetEmmiter", RPCMode.Others, newEmmitNum);

If you are allowing pretty much any change, you'll probably have to send the values by hand:

networkView.RPC("SetEmmiter", RPCMode.Others, matNum, minEmit, maxEmit, grow);

And then assign them by hand in `SetEmmiter`

Technically, this is known as serializing the emmiter. The system doesn't know how to send something that big over the network, so you have to tell it. If you happen to find someone who's already done that, you can skip all this.

You're setting your emitter values every frame. You only need to set them when you switch, so the problem looks worse than it is. You're close. Try this:

// Main code
// FLAMETHROWER=false; // replace this with:
SwitchFire(false); // switch my stats
networkView.RPC("SwitchFire", RPCMode.Others, false); // switch their stats

// FLAMETHROWER=true; // when you add this line, replace it with:
SwitchFire(true);
networkView.RPC("SwitchFire", RPCMode.Others, true);

If you get more guns, change `FLAMETHROWER` to `WEAPON_NUM` and use 0,1,2 instead of true/false.

Move all of the code that changes weapon stuff (including the emitter) to `Switchfire`:

@RPC
// All code to set up weapon on a switch goes here:
function SwitchFire (flamebool : boolean) {
  if(flamebool==true) {
    // apply settings for flamethrower:
    transform.localPosition = flamethrowerPos;          
    renderer.material.mainTexture = Fire;
    renderer.material.shader = Flame;
    particleEmitter.minEnergy = flameLife;
               ....
  }
  else {
    // apply settings for the other weapon:
    transform.localPosition = SpoutPos;
    renderer.material.mainTexture = Tea;
    renderer.material.shader = regShad;
    particleEmitter.minEnergy = 1.5;
            .......
  }
  FLAMETHROWER = flamebool; // save weapon type
  Debug.Log ("recieved fire RPC");
} // end of SwitchFire

An RPC call is a 1-time thing -- it does that "tell other machine to set these locally" you wanted. So even sending 18 variables isn't very expensive. You're probably thinking of the auto-synching it does on a Network.Instantiate, which is sent 15 times/second to keep your player2 and his player2 synched up. Unity doesn't know how to auto-synch emitter properties, and, you're right, it would be a terrible waste of bandwidth.

If you have only 12 types of emitters, you certainly could send the "emitterNumber" and then have the SetEmmiter function use `if(emitNum==1) set it this way...`

The array idea, it seems it might be easier to make an array of transforms in your player script and then just use the inspector to drag in all the emitter prefabs. On a change, you could destroy the current emitter and spawn the new one. I guess you'd need a delay before killing the old one, to prevent the particles from winking out.