UE2 - UT2kX Emitter replication issue - changing color on client

  • Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

Shadow_knight

Carpe diem!
Jan 29, 2008
51
0
6
Prague
Hi all.

I've got just another replication emitter issue. I am playing with Spiral.uc emitter - I wanted to customize it a little by allowing to change the color of the emitter (that is spawned dynamically at runtime). The code below works on the server, but not on the clients. Function calls should be replicated, so is it the problem that the variables Emitters[0].Textures...bla bla aren't ?
Is there some way around this? I've found some emitter tutorials, even with dynamic emitter control, but it just doesn't seem it works. :-/

Code:
#exec OBJ LOAD FILE=EpicParticles.utx

class myEmitter extends Emitter;

replication
{
  reliable if(Role == Role_Authority)
    SetFirstColor, SetSecondColor;
}
simulated function SetFirstColor(Color firstColor)
{
	Emitters[0].ColorScale[1].Color = firstColor;
}

simulated function SetSecondColor(Color secondColor)
{
	Emitters[0].ColorScale[2].Color = secondColor;
}

defaultproperties
{
    Begin Object Class=SpriteEmitter Name=SpriteEmitter2
	UseColorScale=True
        ColorScale(0)=(Color=(B=255,G=255,R=255))
        ColorScale(1)=(RelativeTime=0.200000,Color=(G=170,R=255))
        ColorScale(2)=(RelativeTime=1.000000,Color=(G=217,R=255))
        FadeOutStartTime=1.300000
        FadeOut=True
        FadeInEndTime=0.250000
        FadeIn=True
        MaxParticles=15
        StartLocationShape=PTLS_Sphere
        SphereRadiusRange=(Min=16.000000,Max=16.000000)
        RevolutionsPerSecondRange=(Z=(Min=0.200000,Max=0.500000))
        RevolutionScale(0)=(RelativeRevolution=(Z=2.000000))
        RevolutionScale(1)=(RelativeTime=0.600000)
        RevolutionScale(2)=(RelativeTime=1.000000,RelativeRevolution=(Z=2.000000))
        SpinsPerSecondRange=(X=(Max=4.000000))
        StartSizeRange=(X=(Min=4.000000,Max=4.000000),Y=(Min=4.000000,Max=4.000000),Z=(Min=8.000000,Max=8.000000))
        UniformSize=True
        Texture=Texture'EpicParticles.Flares.HotSpot'
        LifetimeRange=(Min=1.600000,Max=1.600000)
        StartVelocityRadialRange=(Min=-20.000000,Max=-20.000000)
        VelocityLossRange=(X=(Min=0.200000,Max=0.200000),Y=(Min=0.200000,Max=0.200000),Z=(Min=1.000000,Max=1.000000))
        GetVelocityDirectionFrom=PTVD_AddRadial
        UseVelocityScale=True
        VelocityScale(0)=(RelativeVelocity=(X=2.000000,Y=2.000000,Z=2.000000))
        VelocityScale(1)=(RelativeTime=0.600000)
        VelocityScale(2)=(RelativeTime=1.000000,RelativeVelocity=(X=-10.000000,Y=-10.000000,Z=-10.000000))

        LowDetailFactor=+1.0
        Name="SpriteEmitter7"
    End Object
    Emitters(0)=SpriteEmitter'SpriteEmitter2'
    bNoDelete=false
	bReplicateInstigator=True
	bAlwaysRelevant=True
	bDynamicLight=True
	bNetTemporary=False
	bHidden=False
	RemoteRole=ROLE_SimulatedProxy
    CullDistance=+2000.0
}

Thx.

sk
 

Wormbo

Administrator
Staff member
Jun 4, 2001
5,913
36
48
Germany
www.koehler-homepage.de
Replicated functions are always only replicated to the player owning the actor - if it is owned at all. Otherwise they stay where they were called and are executed there.

You could try using replicated variables (try "NetUpdateTime = Level.TimeSeconds - 1;" to force immediate check for changed replicated variable values on the server) and detect possible changes in PostNetReceive().

BTW: I doubt bReplicateInstigator and bDynamicLight will have any useful effect. The Instigator variable is not used in Emitters and therefore doesn't need to be replicated and bDynamicLight is pointless for sprite emitters as those are always unlit.
 

Shadow_knight

Carpe diem!
Jan 29, 2008
51
0
6
Prague
[Solved]

Thanks Wombo. It worked. :) It wasn't even necessary to set NetUpdateTime = Level.TimeSeconds - 1; I just added PostNetReceive() function and added to default properties bNetNotify=True so it gets called. I am posting the working code below (the emitter will start with colors 0,0,0 this way, to change it just set FirstColor and SecondColor to something else in default properties).

Code:
#exec OBJ LOAD FILE=EpicParticles.utx

//-----------------------------------------------------------
//
//-----------------------------------------------------------
class MyEmitter extends Emitter;

var color FirstColor;
var color SecondColor;

replication
{
  reliable if(Role == Role_Authority)
    FirstColor, SecondColor;
}

simulated function SetFirstColor(Color firstC)
{
	FirstColor = firstC;
	//NetUpdateTime = Level.TimeSeconds - 1;
}

simulated function SetSecondColor(Color secondC)
{
	SecondColor = secondC;
	//NetUpdateTime = Level.TimeSeconds - 1;
}

simulated function PostNetReceive()
{
	Emitters[0].ColorScale[1].Color = FirstColor;
	Emitters[0].ColorScale[2].Color = SecondColor;
}

defaultproperties
{
    Begin Object Class=SpriteEmitter Name=SpriteEmitter2
	UseColorScale=True
        ColorScale(0)=(Color=(B=255,G=255,R=255))
        ColorScale(1)=(RelativeTime=0.200000,Color=(G=170,R=255))
        ColorScale(2)=(RelativeTime=1.000000,Color=(G=217,R=255))
        FadeOutStartTime=1.300000
        FadeOut=True
        FadeInEndTime=0.250000
        FadeIn=True
        MaxParticles=15
        StartLocationShape=PTLS_Sphere
        SphereRadiusRange=(Min=16.000000,Max=16.000000)
        RevolutionsPerSecondRange=(Z=(Min=0.200000,Max=0.500000))
        RevolutionScale(0)=(RelativeRevolution=(Z=2.000000))
        RevolutionScale(1)=(RelativeTime=0.600000)
        RevolutionScale(2)=(RelativeTime=1.000000,RelativeRevolution=(Z=2.000000))
        SpinsPerSecondRange=(X=(Max=4.000000))
        StartSizeRange=(X=(Min=4.000000,Max=4.000000),Y=(Min=4.000000,Max=4.000000),Z=(Min=8.000000,Max=8.000000))
        UniformSize=True
        Texture=Texture'EpicParticles.Flares.HotSpot'
        LifetimeRange=(Min=1.600000,Max=1.600000)
        StartVelocityRadialRange=(Min=-20.000000,Max=-20.000000)
        VelocityLossRange=(X=(Min=0.200000,Max=0.200000),Y=(Min=0.200000,Max=0.200000),Z=(Min=1.000000,Max=1.000000))
        GetVelocityDirectionFrom=PTVD_AddRadial
        UseVelocityScale=True
        VelocityScale(0)=(RelativeVelocity=(X=2.000000,Y=2.000000,Z=2.000000))
        VelocityScale(1)=(RelativeTime=0.600000)
        VelocityScale(2)=(RelativeTime=1.000000,RelativeVelocity=(X=-10.000000,Y=-10.000000,Z=-10.000000))

        LowDetailFactor=+1.0
        Name="SpriteEmitter7"
    End Object
    Emitters(0)=SpriteEmitter'SpriteEmitter2'
    bNoDelete=false
	bAlwaysRelevant=True
	bNetTemporary=False
	bHidden=False
	bNetNotify=True
	RemoteRole=ROLE_SimulatedProxy
    CullDistance=+2000.0
}

So just to get things about replication clear for once and for all...
1) If no PlayerController is owning the actor, than the simulated functions called on the actor won't have any effect on clients at all right?
2) To make replication work for EVERY actor we need to use this PostNetReceive() function that is actually called even on clients if bNetNotify is set to true (and maybe bAlwaysRelevant to true?)
3) The client to server replication works just in PlayerController classes or Pawn class that is owned by the PlayerController or in all actor that are owned by PlayerController?

I guess I add this emitter to unrealwiki as an example of replication - some example as this is missing there (that would actually used PostNetReceive() function).

Best,
sk
 
Last edited: