General collision:

sgGenericCH.uc
Code:
//=============================================================================
// sgGenericCH.
// Generic collision hull, written by Higor.
// Remove all collision properties from main actor so it doesn't take damage
// Nukes and neutrons will still harm the main actor, while not harming this one
// So everything is fine anyways.
//
// There's lots of effort in keeping relative positions an bases here in both
// ends of the network.
//=============================================================================
class sgGenericCH expands Actor;

var bool bLocalHull;
var bool bTransmitDamage;
var private actor MyActor;
var private vector RelativePosition;

event PostBeginPlay()
{
	if ( Level.NetMode != NM_Client )
		bLocalHull = True;
}

//This is a mandatory method to setup the hull
//If called after spawn, it will happen before the fist tick, which is required
function Setup( actor Other, float CRadius, float CHeight, optional vector RelativePos)
{
	MyActor = Other;
	SetCollisionSize( CRadius, CHeight);
	if ( RelativePos != vect(0,0,0) )
	{
		RelativePosition = RelativePos;
		SetLocation( Other.Location + RelativePos);
	}
}

//Tick occurs after the main actor's tick
event Tick( float DeltaTime)
{
	local PlayerPawn aPawn;

	if ( MyActor == none || MyActor.bDeleteMe )
	{
		Destroy();
		return;
	}

	if ( VSize( (MyActor.Location-RelativePosition) - Location) > 2)
	{	
		//Move will also move attached objects, SetLocation will make sure this remains in a correct position
		Move( (MyActor.Location - RelativePosition) - Location );

		if ( VSize( (MyActor.Location-RelativePosition) - Location) > 2)
			SetLocation( MyActor.Location - RelativePosition);

		//Eject players if not standing on this structure anymore (crouch bug)
		ForEach BasedActors (class'PlayerPawn', aPawn )
			if ( HSize( aPawn.Location - Location) >= CollisionRadius + aPawn.CollisionRadius )
				aPawn.AddVelocity( vect(0,0,1) );
	}
}

//Forward damage to main actor
event TakeDamage( int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, name DamageType)
{
	if ( bTransmitDamage && bLocalHull )
		MyActor.TakeDamage( Damage, EventInstigator, HitLocation, Momentum, DamageType);
}

static final function float HSize( vector aVec)
{
	return VSize( aVec * vect(1,1,0) );
}

defaultproperties
{
     bHidden=True
     RemoteRole=ROLE_None
     CollisionRadius=1.000000
     CollisionHeight=1.000000
     bCollideActors=True
     bBlockActors=True
     bBlockPlayers=True
     bProjTarget=True
}

Platform edit:
WildcardsPlatform:

Code:
var sgGenericCH TCH;

simulated function FinishBuilding()
{
	Super(sgBuilding).FinishBuilding();
	if (TCH == None)
	{
		TCH=Spawn(class'sgGenericCH',Self,'',Location-vect(0,0,7.5),Rotation);
		TCH.Setup( Self, 60, 15, vect(0,0,-7.5));
		TCH.bTransmitDamage = True;
		Texture=None;

		if (myFX!=None)
		{
			myFX.AmbientGlow=5;
			myFX.ScaleGlow=1.5;
		}
	}
}

simulated event Destruct()
{
	local Pawn p;

	foreach VisibleCollidingActors(class'Pawn', p, 95)
		if ( p.bIsPlayer && (p.Health > 0) && (p.PlayerReplicationInfo != None) )
			p.TakeDamage((Grade/2)+1 , instigator, vect(10,10,0), vect(10,10,0), 'sgSpecial');

	Super(sgBuilding).Destruct();
}

This generic collision hull must be activated using Setup() right after being spawned, it is the only way to ensure proper attachment for movable objects, leaving some of the work done for future implementations.