Jump to content

Need Help on Particles


Allan
 Share

Recommended Posts

Hey ! I would like to change the colour of these lightnings into the player color, does anyone knows how to do it ? I tried so many things but nothing worked, I have the impression that materials are not working like I want with particles  :search:

image.png

  • Like 2
Link to comment
Share on other sites

Hey,

First things first, materials have no effect whatsoever on particles. Ideally the particle actors would have a different format, but that's off topic.

The good news is you can affect particle colors through code! Using this one weird trick (Mostly an unknown engine feature).

Particles support expressions such as this one:

<expr name="emissionrate" from="numbuilders" mul="50.0" max="200.0"/>

Which is interpreted by the code like so:

std::min(m_Max, emitter.m_EntityVariables[m_From] * m_Mul);
std::min(200.0, yourValue * 50.0);

So how does one set the "yourValue" parameter you might ask. Well you can find an example in the Foundation.js code:

let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
if (cmpVisual)
	cmpVisual.SetVariable("numbuilders", this.GetNumBuilders());

So in your case, you might need an extra component let's say ParticlePlayerColor.js

class ParticlePlayerColor
{
	Init()
	{
		this.UpdateColor();
	}

	UpdateColor()
	{
		let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
		if (!cmpVisual)
			return;

		const color = QueryOwnerInterface(this.entity, IID_Player).GetColor();
		cmpVisual.SetVariable("colorr", color.r);
		cmpVisual.SetVariable("colorg", color.g);
		cmpVisual.SetVariable("colorb", color.b);
	}

	OnOwnershipChanged(msg)
	{
		if (msg.to == INVALID_PLAYER)
			return;

		this.UpdateColor();
	}
}

ParticlePlayerColor.prototype.Schema = "<empty/>";

Engine.RegisterComponentType(IID_ParticlePlayerColor, "ParticlePlayerColor", ParticlePlayerColor);

That you can add to your template with 

<ParticlePlayerColor/>

And this little component will take care of updating your particles with the correct values. You need to define colors as expressions in your particle file:

    <expr name="color.r"  from="colorr" mul="1.0" max="1.0"/>
    <expr name="color.g" from="colorg"  mul="1.0" max="1.0"/>
    <expr name="color.b"  from="colorb"  mul="1.0"  max="1.0"/>

Do note that it will not be the exact color you want as the particle texture say <texture>art/textures/particles/dust_256a.png</texture> as its own, but it should get close.

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

30 minutes ago, Stan&#x60; said:

That you can add to your template with 

<ParticlePlayerColor/>

Hey, I think I understood the main part of this, thanks for being this clear ! But there is a little misunderstanding for this. 

When you say template, what file do you mean ? Because I tried to put it on every single XML files attached to a building (simulation/templates, actors, particles flie, particles actor...) but nothing worked, i keep having these : 

On particle file (same on particle actor file) :

image.png.7c0b8b66847385f4192a4a2e6adad835.png

On building template file :

image.png.1377fd100c3c70080a06c413e6f8a8cb.png

 

So I think I did something wrong but I don't know what :search:

Link to comment
Share on other sites

My bad, you also need an interface for that component :) 

in simulation/components/interfaces add a new file called ParticlePlayerColor.js

With this content

Engine.RegisterInterface("ParticlePlayerColor");

 

  • Like 1
Link to comment
Share on other sites

I put some warns in the .js component and it seems that it's working, the values (color.r-g-b) change when I change player color. But it's not updating the color of the texture, it's still red even if i'm a the green or bleu team :search:

Link to comment
Share on other sites

48 minutes ago, Allan said:

I put some warns in the .js component and it seems that it's working, the values (color.r-g-b) change when I change player color. But it's not updating the color of the texture, it's still red even if i'm a the green or bleu team :search:

You need to use a texture without colors. Such as the one for dust it doesn't colorize it just reduces the rgb value of each pixel so if you have a blue texture you can only do shades of blue.

  • Like 1
Link to comment
Share on other sites

Posted (edited)

Ok I tried with this and it doesnt work, I think I didn't understand well the concept of drawing a texture without colors :search:

It seems like the code is working but the color of the player is not being attached /put to the particle color. The color of the particule doesn't change 

 

image.png

Edited by Allan
Link to comment
Share on other sites

I tried with it and nothing has been colored. Here is my particule file : 

<?xml version="1.0" encoding="utf-8"?>
<particles>

    <texture>art/textures/particles/red_lightning.png</texture>
    <blend mode="over"/>

    <!-- <start_full/> -->

    <constant name="emissionrate" value="150.0"/>
    <uniform name="lifetime" min="0.1" max="1.0"/>

    <constant name="position.y" value="0"/>

    <uniform name="angle" min="-3.14" max="3.14"/>

    <uniform name="velocity.x" min="-5.0" max="5.0"/>
    <uniform name="velocity.y" min="-5.0" max="5.0"/>
    <uniform name="velocity.z" min="-5.0" max="5.0"/>
    <!-- <uniform name="velocity.angle" min="-0.5" max="0.5"/> -->

    <uniform name="size" min="1.0" max="6.5"/>
	<constant name="size.growthRate" value="25.0"/>

    <expr name="color.r"  from="colorr" mul="1.0" max="1.0"/>
    <expr name="color.g" from="colorg"  mul="1.0" max="1.0"/>
    <expr name="color.b"  from="colorb"  mul="1.0"  max="1.0"/>
    

    <ParticlePlayerColor/>

</particles>

 

 

Link to comment
Share on other sites

<?xml version="1.0" encoding="utf-8"?>
<particles>
    <texture>art/textures/particles/dust_256a.png</texture>
    <blend mode="over"/>
    <expr name="emissionrate" from="numbuilders" mul="50.0" max="200.0"/>
    <uniform name="lifetime" min="3.0" max="5.0"/>
    <uniform name="position.x" min="-8.0" max="8.0"/>
    <uniform name="position.z" min="-8.0" max="8.0"/>
    <constant name="position.y" value="1.0"/>
    <uniform name="angle" min="-3.14" max="3.14"/>
    <uniform name="velocity.x" min="-1.5" max="1.0"/>
    <uniform name="velocity.y" min="2.0" max="3.5"/>
    <uniform name="velocity.z" min="-1.5" max="1.0"/>
    <uniform name="velocity.angle" min="-2.0" max="3.0"/>
    <uniform name="size" min="5.0" max="7.5"/>
    <expr name="color.r"  from="colorr" mul="1.0" max="1.0"/>
    <expr name="color.g" from="colorg"  mul="1.0" max="1.0"/>
    <expr name="color.b"  from="colorb"  mul="1.0"  max="1.0"/>
    <force y="-2.5"/>
</particles>

This is the one I tested with.

<ParticlePlayerColor/>

Should only be in the building template in simulation/templates

 

  • Like 1
Link to comment
Share on other sites

Posted (edited)

Ok some weird things happened. To test your code, I have to put the emissionrate on constant, if I don't do this I can't see anything. The result is the screenshot linked to the post. I put the <ParticlePlayerColor/> in the building template as you said, i put warns so I can say that the component is working.

 

But as you can see, the result is not what I really want :search:

 

After some tests, I can see the colour changing when testing your code, but it seems like it's changing on greyscale, the dust appears a little darker but not blue.

 

After more tests, I thinkn the problem is not resolvable by this way because we can't change the RGB of the texture directly, so I can't have red particule for red player, blue particles for blue player etc... 

image.png

Edited by Allan
To be more precise, after some tests
Link to comment
Share on other sites

Hmm that's really strange because I tested that code earlier and I had blue and red dust X)

And yeah emission rate has to be constant I hacked the foundation code that relies on builder numbers.

What values do you have in player colors ?

I will test some more tomorrow

  • Like 1
Link to comment
Share on other sites

Posted (edited)

So I put warns in UpdateColor function

class ParticlePlayerColor
{
	Init()
	{
		this.UpdateColor();
	}

	UpdateColor()
	{
		let cmpVisual = Engine.QueryInterface(this.entity, IID_Visual);
		if (!cmpVisual)
			return;

		const color = QueryOwnerInterface(this.entity, IID_Player).GetColor();
		cmpVisual.SetVariable("colorr", color.r);
		cmpVisual.SetVariable("colorg", color.g);
		cmpVisual.SetVariable("colorb", color.b);
		warn(color.r);
		warn(color.g);
		warn(color.b);
	}

	OnOwnershipChanged(msg)
	{
		if (msg.to == INVALID_PLAYER)
			return;

		this.UpdateColor();
	}
}

ParticlePlayerColor.prototype.Schema = "<empty/>";

Engine.RegisterComponentType(IID_ParticlePlayerColor, "ParticlePlayerColor", ParticlePlayerColor);

 

And that's the result for Blue

image.png.d2f7d2bf907eb3ba4aab86eae19cba9b.png

Red :

image.png.243ab51a082853f39d6060452c22b06e.png

Green

image.png.d2b3270741dc40f50d5bcb9400953dcc.png

Yellow

image.png.f27ef6a15572a1f2df3ebdb927bb9c7f.png

 

Maybe you hacked something else that i don't have on my version ? x)

Edited by Allan
Link to comment
Share on other sites

screenshot0023.pngscreenshot0022.pngscreenshot0021.pngscreenshot0020.png

 

Made a few more tests with this particle:

<?xml version="1.0" encoding="utf-8"?>
<particles>

    <texture>art/textures/particles/dust_256a.png</texture>
    <blend mode="over"/>

    <constant name="emissionrate" value="1000.0"/>
    <constant name="lifetime" value="10.0"/>
    <uniform name="angle" min="-3.14" max="3.14"/>
    <uniform name="velocity.x" min="-1.5" max="1.0"/>
    <uniform name="velocity.y" min="2.0" max="3.5"/>
    <uniform name="velocity.z" min="-1.5" max="1.0"/>
    <uniform name="velocity.angle" min="-2.0" max="3.0"/>
    <uniform name="size" min="7.4" max="7.5"/>
    <expr name="color.r"  from="colorr" mul="1.0" max="1.0"/>
    <expr name="color.g" from="colorg"  mul="1.0" max="1.0"/>
    <expr name="color.b"  from="colorb"  mul="1.0" max="1.0"/>

    <force y="-2.5"/>

</particles>

 

 

Custom actor:

 

<?xml version="1.0" encoding="utf-8"?>
<actor version="1">
  <castshadow/>
  <group>
    <variant frequency="1" name="Carthaginian House">
      <mesh>skeletal/celt_trader.dae</mesh>
      <props>
        <prop actor="props/structures/decals/dirt_small.xml" attachpoint="root"/>
        <prop actor="particle/construction_dust.xml" attachpoint="root"/>
      </props>
      <textures>
        <texture file="structural/kart_struct.dds" name="baseTex"/>
        <texture file="structural/kart_struct_norm.png" name="normTex"/>
        <texture file="structural/kart_struct_spec.png" name="specTex"/>
      </textures>
    </variant>
  </group>
  <group>
    <variant frequency="1" name="ungarrisoned"/>
    <variant name="garrisoned">
      <props>
        <prop actor="props/special/common/garrison_flag_kart.xml" attachpoint="garrisoned"/>
      </props>
    </variant>
  </group>
  <group>
    <variant name="alive" frequency="1"/>
    <variant file="structures/cart/light_damage.xml"/>
    <variant file="structures/cart/medium_damage.xml"/>
    <variant file="structures/cart/heavy_damage.xml"/>
    <variant file="structures/cart/destruction_small.xml"/>
  </group>
  <material>player_trans_parallax_spec.xml</material>
</actor>

I used a custom texture for the following one:

screenshot0025.png

I used the following texture: -> (It's not all white)

image.png

Few notes:

Hotloading particles is crashy as in changing a few values can crash the game.

SetVariable won't work if you hotload particles (each time you change a value in the XML or the modle you have to restart the match) Fortunately you can use the following code in your tests (Don't use in production) that will keep forcing the variables at each frame.

class ParticlePlayerColor
{
	... Don't touch the previous code.

    OnUpdate()
    {
        this.UpdateColor();
    }
}

As for the grey in the middle it's due to particles decaying maybe it's an engine bug @vladislavbelov would know.

 

image.png

  • Like 1
Link to comment
Share on other sites

Ok I've got the same results as you with this, that's a little victory. But if I don't put this code in the .js component, the particle don't take the player color, and I don't know why :search:

And as you said, it seems like it updates particles at every frame, so the game starts being laggy 

1 hour ago, Stan&#x60; said:
class ParticlePlayerColor
{
	... Don't touch the previous code.

    OnUpdate()
    {
        this.UpdateColor();
    }
}

 

Link to comment
Share on other sites

Mmh that's a bit strange. Does the building switch variants a lot (Does it have animations or specific states)?

Unfortunately there is no GetVariable so we cannot check if the values changed. Maybe there is an event we should be listening to.

Link to comment
Share on other sites

Sorry i'm a bit late

Here is the template of the building :

<?xml version="1.0" encoding="utf-8"?>
<Entity parent="template_structure_civic_command_base">

<Attack>
    <Ranged>
      <AttackName>Bow</AttackName>
       <Damage>
        <Pierce>40</Pierce>
        <Crush>40</Crush>
      </Damage>
      <MaxRange>100</MaxRange>
      <PrepareTime>0</PrepareTime>
      <RepeatTime>100</RepeatTime>
      <Projectile>
        <Speed>100</Speed>
        <Spread>1.5</Spread>
        <Gravity>0</Gravity>
        <FriendlyFire>false</FriendlyFire>
        <LaunchPoint y="3"/>
        <ActorName>props/units/weapons/laser_ammo.xml</ActorName>
      </Projectile>
      <PreferredClasses datatype="tokens">Human</PreferredClasses>
      <RestrictedClasses datatype="tokens">Spaceship Structure</RestrictedClasses>
      <RangeOverlay>
        <LineTexture>outline_border.png</LineTexture>
        <LineTextureMask>outline_border_mask.png</LineTextureMask>
        <LineThickness>0.175</LineThickness>
      </RangeOverlay>
    </Ranged>
  </Attack>

  <Footprint>
    <Square width="140.0" depth="120.0"/>
    <Height>8.0</Height>
  </Footprint>

  <Health>
    <DeathType>vanish</DeathType>
    <Max>2500</Max>
    <RegenRate>0</RegenRate>
    <IdleRegenRate>0</IdleRegenRate>
    <Unhealable>false</Unhealable>
  </Health>

  <Identity>
    <Civ>robot</Civ>
    <Icon>structures/robot/powerstation.png</Icon>
    <GenericName>Power Station</GenericName>
    <SpecificName>Power Station</SpecificName>
    <Tooltip>Main Building of the Robot civilisation. Make you able to train Buildobots, Spybots and to research many useful technologies to improve them.</Tooltip>
    <History>This building is very important for the Robots because he shelters the Quantum Computer which manages the AI of all the civilisation. Robots will be very agressive if they see someone or something attacking it.</History>
  </Identity>

  <Obstruction>
    <Static width="140.0" depth="120.0"/>
  </Obstruction>

  <ParticlePlayerColor/>

  <Researcher>
		<Technologies datatype="tokens">
      phase_village_robot
      phase_town_robot
      phase_city_robot
		</Technologies>
  </Researcher>

  <Resistance>
    <Entity>
      <Damage>
      <Pierce>20</Pierce>
      <Hack>12</Hack>
      </Damage>
    </Entity>
  </Resistance>

  <Sound>
    <SoundGroups>
      <select>interface/select/building/command_base_select.xml</select>
    </SoundGroups>
  </Sound>

  <VisualActor>
    <Actor>structures/robot/command_base.xml</Actor>
    <FoundationActor>structures/fndn_20x20.xml</FoundationActor>
  </VisualActor>

</Entity>

Here is the actor of the building

 

<?xml version="1.0" encoding="UTF-8"?>
<actor version="1">
  <castshadow/>
  <group>
    <variant frequency="100" name="Base">
      <mesh>structures/robot/command_base.dae</mesh>
      <props>
        <prop actor="particles/big_red_lightning.xml" attachpoint="lightning"/>
      </props>
      <textures>
        <texture file="structures/robot/command_base.png" name="baseTex"/>
        <texture file="null_white.dds" name="specTex"/>
      </textures>
    </variant>
  </group>
  <material>player_trans_spec.xml</material>
</actor>

 

Link to comment
Share on other sites

Ok I found the problem, I feel soooo dumb :lol:

 

The fact is that I was testing these particules on a map where is only one player, so the game consider that is a win and ask me if I want to go back to lobby or stay in the game. So it attributes the gaia color (grey), and not the player color, because i'm not a player. I tested the particules without the OnUpdate function in a normal map and it's working. 

  • Haha 1
Link to comment
Share on other sites

Ok I did a new texture more simple to have a lightning effect, here are some "good" results

Yellow
image.png.0ccc49c3a0c06ee6d4d2097d439ab471.png

Green

image.png.14ddbee7f7fcb01c1507cda08e6644ec.png

 

Do you have any idea to improve that ? Because the render with the red lightning at the beginning was way better than this :search:

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...