Page 1 of 1

Duplicated Actors removal - a solution

Posted: Fri Apr 27, 2018 10:17 pm
by Nelsona
Due to whatever import operated when a map is being build, something is not going well and this will cause existence of some duplicated Actors. I don't know if this is less harmful or not but I did not liked such "features". I did a builder able to track these and I was trying to do it accurate :? What for so accurate ?
While we know that there are duplicates, the goal is to re-wrap them rather than to know exactly how many they are because map will stay screwed if they are not wrapped properly.
I wrote something for duplicated actors which do seems to have results, working at Engine speed rather than blabbering manually with these actors with a bool check set to True and a single click on builder.
After crashing Editor a few times trying to get something, finally I got a function as a personal idea how to remove duplicates but keeping a copy of original actor which was duplicated. In a normal map (not one with 5000+ actors), this method has worked like a charm.

Code: Select all

final function DestroyDupes()
{
	local Actor A, A1;
	local int j;

	foreach MyMap.AllActors(class'Actor',A)
	{
		if ( A.Tag == 'Duplicated' )
		{
			A.Destroy();
			j++;
			Continue;
		}
		else
		{
			foreach MyMap.AllActors(class'Actor',A1,A.Tag)
			{
				if ( string(A1.Name) == string(A.Name) )
					A1.Tag = 'Duplicated';
			}
		}
	}
	if ( j > 0 )
		log ("Removed"@j@"duplicated Actors. Do the check again...");
	else
		log ("There is nothing duplicated for removal.");
}
Map tested was one of those AncientCastle with 27 Duplicated actors removed but still having original ones.

Re: Duplicated Actors removal - a solution

Posted: Sun Apr 29, 2018 2:51 pm
by Nelsona
But because above method will require some editing due to new Tag used, I changed the code from this builder as follows:

Code: Select all

final function DestroyDupes()
{
	local Actor A, A1;
	local int j, i;
	local bool bTagged;

	foreach MyMap.AllActors(class'Actor',A)
	{
		if ( A.Tag == 'Duplicated' )
		{
			A.Destroy();
			j++;
			Continue;
		}
		else
		{
			foreach MyMap.AllActors(class'Actor',A1,A.Tag)
			{
				if ( string(A.Name) == string(A1.Name) )
				{
					i++;
					if ( i > 1 )
					{
						A1.Tag = 'Duplicated';
						i = 0;
					}
				}
			}
			i = 0;
		}
	}
	A = None;
	foreach MyMap.AllActors(class'Actor',A,'Duplicated')
		A.Tag = A.default.Tag;
	if ( j > 0 )
		log ("Removed"@j@"duplicated Actors. Do the check again...");
	else
		log ("There is nothing duplicated for removal.");
}
As result Actors which initially were duplicated are tagged with a null tag aka None. Less damaging than solution presented above... which was requiring a map-check.
These might not be the best ever solutions but... maybe are helping someone else...