RealFireFX isn't despawning

Discussions about Coding and Scripting
Post Reply
User avatar
Gustavo6046
Godlike
Posts: 1462
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Resident Wallaby
Location: Porto Alegre, Brazil
Contact:

RealFireFX isn't despawning

Post by Gustavo6046 »

So I started to mess some bit with UnrealScript.

In theory, we have the spawner

Code: Select all

//=============================================================================
// RealFireSpawner.
//=============================================================================
class RealFireSpawner expands Effects;

var(Fire)	float		FireScale;
var(Fire)	float		FireRate;
var(Fire)	float		Fire1Weight;
var(Fire)	float		Fire2Weight;
var(Fire)	float		Fire3Weight;
var(Fire)	Texture		FireTexture1;
var(Fire)	Texture		FireTexture2;
var(Fire)	Texture		FireTexture3;
var(Fire)	float		FireDuration;
var(Fire)	Vector		FireOffset;
var(Fire)	Vector		FireVelocity;
var(Fire)	Vector		FireVelocityOffset;
var(Fire)	float		FireDespawnRate;
var(Fire)	EPhysics	FirePhysics;
var(Fire)	bool		bDamagingFire;
var(Fire)	float		FireDamageAmount;
var(Fire)	float		FireDamageRadius;
var(Fire)	float		FireDamageMomentum;
/*
var(Fire)	Color		Fire1Color;
var(Fire)	Color		Fire2Color;
var(Fire)	Color		Fire3Color;
*/

function BeginPlay()
{
        //Starts fire loop!
	SetTimer(1.0 / FireRate, true);
}

function Tick(float TimeDelta)
{
        //Assures that the fire doesn't last forever unless specified
	if ( TimeDelta > FireDuration && FireDuration > 0 )
		Destroy();
}

function Timer()
{
        //All these lines that set the fire properties
	local RealFireFX fire1, fire2, fire3;

	fire1 = Spawn(class'RealFireFX', self, '__realfirefx__', Location + (FireOffset * (frand() - 0.5)));
	fire2 = Spawn(class'RealFireFX', self, '__realfirefx__', Location + (FireOffset * (frand() - 0.5)));
	fire2 = Spawn(class'RealFireFX', self, '__realfirefx__', Location + (FireOffset * (frand() - 0.5)));

	if ( fire1 == None || fire2 == None || fire3 == None )
		return;

	fire1.Texture = FireTexture1;
	fire2.Texture = FireTexture2;
	fire3.Texture = FireTexture3;

	fire1.Sprite = FireTexture1;
	fire2.Sprite = FireTexture2;
	fire3.Sprite = FireTexture3;

	fire1.Drawscale = frand() * FireScale;
	fire2.Drawscale = frand() * FireScale;
	fire3.Drawscale = frand() * FireScale;

	fire1.bDamaging = bDamagingFire;
	fire2.bDamaging = bDamagingFire;
	fire3.bDamaging = bDamagingFire;

	fire1.Velocity = FireVelocity + ((frand() - 0.5) * FireVelocityOffset);
	fire2.Velocity = FireVelocity + ((frand() - 0.5) * FireVelocityOffset);
	fire3.Velocity = FireVelocity + ((frand() - 0.5) * FireVelocityOffset);

	fire1.SetPhysics(FirePhysics);
	fire2.SetPhysics(FirePhysics);
	fire3.SetPhysics(FirePhysics);

	fire1.Drawscale *= frand() * Fire1Weight;
	fire2.Drawscale *= frand() * Fire2Weight;
	fire3.Drawscale *= frand() * Fire3Weight;

	fire1.DespawnRate = FireDespawnRate;
	fire2.DespawnRate = FireDespawnRate;
	fire3.DespawnRate = FireDespawnRate;

	fire1.FVelocity = FireVelocity;
	fire2.FVelocity = FireVelocity;
	fire3.FVelocity = FireVelocity;

	fire1.VelocityOffset = FireVelocityOffset;
	fire2.VelocityOffset = FireVelocityOffset;
	fire3.VelocityOffset = FireVelocityOffset;

	fire1.DamageAmount = FireDamageAmount;
	fire2.DamageAmount = FireDamageAmount;
	fire3.DamageAmount = FireDamageAmount;

	fire1.DamageRadius = FireDamageRadius;
	fire2.DamageRadius = FireDamageRadius;
	fire3.DamageRadius = FireDamageRadius;

	fire1.DamageMomentum = FireDamageMomentum;
	fire2.DamageMomentum = FireDamageMomentum;
	fire3.DamageMomentum = FireDamageMomentum;

/*
	fire1.LightHue = Fire1Color.H;
	fire1.LightSaturation = 255 - Fire1Color.LightSaturation;
	fire1.LightBrightness = Fire1Color.LightBrightness;
	fire2.LightHue = Fire2Color.LightHue;
	fire2.LightSaturation = 255 - Fire2Color.LightSaturation;
	fire2.LightBrightness = Fire2Color.LightBrightness;
	fire3.LightHue = Fire3Color.LightHue;
	fire3.LightSaturation = 255 - Fire3Color.LightSaturation;
	fire3.LightBrightness = Fire3Color.LightBrightness;
*/
}
and the fire itself

Code: Select all

//=============================================================================
// RealFireFX.
//=============================================================================
class RealFireFX expands Effects;

var				bool	bDamaging;
var				float	DespawnRate;
var				Vector	FVelocity;
var				Vector	VelocityOffset;
var				float	DamageAmount;
var				float	DamageRadius;
var				float	DamageMomentum;

function Tick(float delta)
{
	DrawScale -= frand() * DespawnRate;
	Velocity = FVelocity + ((frand() * 2 - 1) * VelocityOffset);

	if ( bDamaging )
		HurtRadius(DamageAmount, DamageRadius, 'Fire', DamageMomentum, Location);

	if ( DrawScale < 0.1 )
		Destroy();
}
.

However, a) the fire is using Engine.Actor for sprite instead of the one I specified, and b) the fire is spawning infinitely, without moving or even despawning after a time!

Please help! What did I do wrong now?

(also, it seems fire1, fire2 and fire3 at the spawner's Timer() function aren't set by Spawn() calls... :???: )
"Everyone is an idea man. Everybody thinks they have a revolutionary new game concept that no one else has ever thought of. Having cool ideas will rarely get you anywhere in the games industry. You have to be able to implement your ideas or provide some useful skill. Never join a project whose idea man or leader has no obvious development skills. Never join a project that only has a web designer. You have your own ideas. Focus on them carefully and in small chunks and you will be able to develop cool projects."

Weapon of Destruction
User avatar
'Zac
Experienced
Posts: 111
Joined: Tue Jul 29, 2014 9:35 pm
Personal rank: Who knows.
Location: NC

Re: RealFireFX isn't despawning

Post by 'Zac »

Also, use PostBeginPlay() i think that'll give it a more prioritized spawn.
When setting the damage, velocity, texture and all i recommend using a function, for say " function SetTextures(texture Fire1, texture Fire2, texture Fire3) " and " function SetNewVolicity(vector Vel, vector Mom, vector location, vector rotation)", its a better workflow and directly changing variables like that from another class is a tad slower, but both work.

Try extending the spawner off Keypoints or ThingFactor or something similar, effects in my opinion are just decor, actors without much code at all and just animation. The fire effect itself can stay, just reference it be spawned in the spawner the way the ThingFactory would, but simpler and easy like youre making it with scale and all. This also reminds me on the UDK/UE3's particle system maker in its editor, you should take a look at a tutorial or show of it on youtube or something because its basically exactly what youre doing and i think thats great.
Prophunt for UT99!!!
Image
Github
User avatar
Gustavo6046
Godlike
Posts: 1462
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Resident Wallaby
Location: Porto Alegre, Brazil
Contact:

Re: RealFireFX isn't despawning

Post by Gustavo6046 »

Thanks for the recommendations, Zac.

However, I still need to find a reason for why Spawn() isn't returning the actors!
I could just group the settings in a different way inside

Code: Select all

function Timer()
{
    fire1 = Spawn(...)
    // repeat for fire2 and fire3

    if ( fire1 != None )
    {
        //set fire1's properties
    }

    if ( fire2 != None )
    {
        //set fire2's properties
    }

    if ( fire3 != None )
    {
        //set fire3's properties
    }
}
these if statements. I guess if just ONE of them doesn't spawn (in this case fire3), the entire property setting is aborted to avoid Accessed Nones.

EDKT: Oh snap, fire2 is set twice! The 2nd time should instead set fire3!
"Everyone is an idea man. Everybody thinks they have a revolutionary new game concept that no one else has ever thought of. Having cool ideas will rarely get you anywhere in the games industry. You have to be able to implement your ideas or provide some useful skill. Never join a project whose idea man or leader has no obvious development skills. Never join a project that only has a web designer. You have your own ideas. Focus on them carefully and in small chunks and you will be able to develop cool projects."

Weapon of Destruction
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: RealFireFX isn't despawning

Post by Higor »

Cool code, too bad under the current engine it can cause massive memory consumption if not used sparingly.

Facts:
1 - Until Garbage Collection, destroyed actors remain in allocated memory.
Spawning actors does not replace old actors, they allocate new memory.
2 - Use proper terms, or you won't understand your code when you look at it in a week.
--- NumTicks, TicksLeft
--- LifeSpan, ElapsedTime
--- SpawnRate, SpawnFrequency
--- ParticleLife
--- Alpha, Delta
3 - The engine provides various simple, native controlled routines to avoid adding code.
If your model is simple enough, you can use these routines and simplify everything by simply tweaking properties (i named 'simple' 4 times with this line, rememeber: simplicity, that's 5 times now).
4 - If you have no idea where to start, "put the project on paper" be it on a post, a note or on your mind.
Knowing all of the details before you even start coding is a huge way to get proper help as well as make it easier for yourself to start and finish this in less than 60 minutes.
User avatar
Gustavo6046
Godlike
Posts: 1462
Joined: Mon Jun 01, 2015 7:08 pm
Personal rank: Resident Wallaby
Location: Porto Alegre, Brazil
Contact:

Re: RealFireFX isn't despawning

Post by Gustavo6046 »

Higor wrote:3 - The engine provides various simple, native controlled routines to avoid adding code.
If your model is simple enough, you can use these routines and simplify everything by simply tweaking properties (i named 'simple' 4 times with this line, rememeber: simplicity, that's 5 times now).
Higor, thanks for consideration :) , but ...... what routines?

BTW, why is it lagging so much? I'm not doing great use of Tick() IIRC. Other than that WE CAN NOW CATCH ON FIRE!!! And some more cool stuff!

RealFireSpawner:

Code: Select all

//=============================================================================
// RealFireSpawner.
//=============================================================================
class RealFireSpawner expands Effects;

var(Fire)	float		FireScale;
var(Fire)	float		FireRate;
var(Fire)	float		Fire1Weight;
var(Fire)	float		Fire2Weight;
var(Fire)	float		Fire3Weight;
var(Fire)	Texture		FireTexture1;
var(Fire)	Texture		FireTexture2;
var(Fire)	Texture		FireTexture3;
var(Fire)	float		FireDuration;
var(Fire)	Vector		FireOffset;
var(Fire)	Vector		FireVelocity;
var(Fire)	Vector		FireVelocityOffset;
var(Fire)	float		FireDespawnRate;
var(Fire)	EPhysics	FirePhysics;
var(Fire)	bool		bDamagingFire;
var(Fire)	float		FireDamageAmount;
var(Fire)	float		FireDamageRadius;
var(Fire)	float		FireDamageMomentum;
var(Fire)	float		CatchingFireTime;
var			float		elapsedtime;

function BeginPlay()
{
	SetTimer(1.0 / FireRate, true);
}

function Tick(float TimeDelta)
{
	elapsedtime += TimeDelta;

	if ( elapsedtime > FireDuration && FireDuration >= 0 )
		Destroy();
}

function Extinguish(float ExtinguishForce)
{
	FireScale -= ExtinguishForce;

	if ( FireScale < 0.1 )
		Destroy();
}

function Timer()
{
	local RealFireFX fire1, fire2, fire3;

	fire1 = Spawn(class'RealFireFX', self, '__realfire_normal__', Location + (FireOffset * (frand() - 0.5)));
	fire2 = Spawn(class'RealFireFX', self, '__realfire_normal__', Location + (FireOffset * (frand() - 0.5)));
	fire3 = Spawn(class'RealFireFX', self, '__realfire_normal__', Location + (FireOffset * (frand() - 0.5)));

	if ( fire1 != None && FireTexture1 != None )
	{
		fire1.Texture = FireTexture1;
		fire1.Sprite = FireTexture1;
		fire1.Drawscale = frand() * FireScale;
		fire1.bDamaging = bDamagingFire;
		fire1.Velocity = FireVelocity + ((frand() - 0.5) * FireVelocityOffset);
		fire1.SetPhysics(FirePhysics);
		fire1.Drawscale *= frand() * Fire1Weight;
		fire1.DespawnRate = FireDespawnRate;
		fire1.FVelocity = FireVelocity;
		fire1.VelocityOffset = FireVelocityOffset;
		fire1.DamageAmount = FireDamageAmount;
		fire1.DamageRadius = FireDamageRadius;
		fire1.DamageMomentum = FireDamageMomentum;
	}
	else if ( fire1 != None ) fire1.Destroy();

	if ( fire2 != None && FireTexture2 != None )
	{
		fire2.Texture = FireTexture2;
		fire2.Sprite = FireTexture2;
		fire2.Drawscale = frand() * FireScale;
		fire2.bDamaging = bDamagingFire;
		fire2.Velocity = FireVelocity + ((frand() - 0.5) * FireVelocityOffset);
		fire2.SetPhysics(FirePhysics);
		fire2.Drawscale *= frand() * Fire2Weight;
		fire2.DespawnRate = FireDespawnRate;
		fire2.FVelocity = FireVelocity;
		fire2.VelocityOffset = FireVelocityOffset;
		fire2.DamageAmount = FireDamageAmount;
		fire2.DamageRadius = FireDamageRadius;
		fire2.DamageMomentum = FireDamageMomentum;
	}
	else if ( fire2 != None ) fire2.Destroy();

	if ( fire3 != None && FireTexture3 != None )
	{
		fire3.Texture = FireTexture3;
		fire3.Sprite = FireTexture3;
		fire3.Drawscale = frand() * FireScale;
		fire3.bDamaging = bDamagingFire;
		fire3.Velocity = FireVelocity + ((frand() - 0.5) * FireVelocityOffset);
		fire3.SetPhysics(FirePhysics);
		fire3.Drawscale *= frand() * Fire3Weight;
		fire3.DespawnRate = FireDespawnRate;
		fire3.FVelocity = FireVelocity;
		fire3.VelocityOffset = FireVelocityOffset;
		fire3.DamageAmount = FireDamageAmount;
		fire3.DamageRadius = FireDamageRadius;
		fire3.DamageMomentum = FireDamageMomentum;
	}
	else if ( fire3 != None ) fire3.Destroy();
}
RealFireFX:

Code: Select all

//=============================================================================
// RealFireFX.
//=============================================================================
class RealFireFX expands Effects;

var				bool	bDamaging;
var				float	DespawnRate;
var				Vector	FVelocity;
var				Vector	VelocityOffset;
var				float	DamageAmount;
var				float	DamageRadius;
var				float	DamageMomentum;

function Tick(float delta)
{
	if ( Owner == None )
		Destroy();

	DrawScale -= frand() * DespawnRate;
	Velocity = FVelocity + ((frand() * 2 - 1) * VelocityOffset);

	if ( bDamaging )
		HurtRadius(DamageAmount, DamageRadius, 'Fire', DamageMomentum, Location);

	if ( DrawScale < 0.1 )
		Destroy();
}

function Touch(Actor Other)
{
	local	RealFireOnTarget	CatchingFire;
	local	RealFireOnTarget	Fires;

	if ( !  Other.IsA(class'Pawn'.Name)
		 || RealFireSpawner(Owner).CatchingFireTime <= 0
    	 || ( Owner.IsA(class'RealFireOnTarget'.Name)
		 && RealFireOnTarget(Owner).BurningActor == Other ) )
		return;

	foreach AllActors(class'RealFireOnTarget', Fires)
	{
		if ( Fires.BurningActor == Other )
			return;
	}

	CatchingFire = Spawn(class'RealFireOnTarget', self, '__realfire_targetburn__', Other.Location, Other.Rotation);

	if ( CatchingFire == None )
		return;

	//Sets all relevant properties of CatchingFire
	CatchingFire.BurningActor = Other;
	CatchingFire.FireDuration = RealFireSpawner(Owner).CatchingFireTime;
	CatchingFire.FireTexture1 = RealFireSpawner(Owner).FireTexture1;
	CatchingFire.FireTexture2 = RealFireSpawner(Owner).FireTexture2;
	CatchingFire.FireTexture3 = RealFireSpawner(Owner).FireTexture3;
	CatchingFire.Fire1Weight  = RealFireSpawner(Owner).Fire1Weight;
	CatchingFire.Fire2Weight  = RealFireSpawner(Owner).Fire2Weight;
	CatchingFire.Fire3Weight  = RealFireSpawner(Owner).Fire3Weight;
	CatchingFire.FireRate	  = RealFireSpawner(Owner).FireRate;
}
RealFireOnTarget:

Code: Select all

//=============================================================================
// RealFireOnTarget.
//=============================================================================
class RealFireOnTarget expands RealFireSpawner;

var(Fire)	Actor	BurningActor;

function PreBeginPlay()
{
	SetPhysics(PHYS_Falling);
}

function Tick(float delta)
{
	Super.Tick(delta);
	
	if ( BurningActor == None )
		Destroy();

	SetLocation(BurningActor.Location);
	SetRotation(BurningActor.Rotation);
}
This is so far the most succesful... I mean promising code I ever did!!! :D
"Everyone is an idea man. Everybody thinks they have a revolutionary new game concept that no one else has ever thought of. Having cool ideas will rarely get you anywhere in the games industry. You have to be able to implement your ideas or provide some useful skill. Never join a project whose idea man or leader has no obvious development skills. Never join a project that only has a web designer. You have your own ideas. Focus on them carefully and in small chunks and you will be able to develop cool projects."

Weapon of Destruction
Post Reply