I search for solutions in this order: Past Code, Unreal Source, Wiki, BUF, groups.yahoo, google, screaming at monitor. – RegularX

Legacy:Wizzie/OnJoinSpectatorCamera

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

This is a codesnippet from my PlayerController. When a player joins the server, they'll have to choose a team in the teamselect menu. While they are choosing i change the camerlocation of the player to random locations of the map using current available actors as locations.

class pPlayerController extends PlayerController;
 
	...
	...
	...
 
auto state OnJoinSpectating
{
	simulated function SetSpectatorCamera()
	{
		local int i;
		local array<Actor> ActorList;
		local Actor aActor;
		local float dist, bestdist;
		local vector CameraLocation, TargetLocation, best, tmp;
	    local Vector hitloc, hitnormal;
	    local float SearchTimelimit;
 
		// Get a list of current actors and skip those we don't want
		ForEach AllActors(class'Actor', aActor)
		{
			// Actor types we should'nt use
			if( Controller(aActor) != none ||
				AntiPortalActor(aActor) != none ||
				Emitter(aActor) != none ||
				xEmitter(aActor) != none ||
				BlockingVolume(aActor) != none ||
				Info(aActor) != none ||
				Inventory(aActor) != none ||
				InventorySpot(aActor) != none ||
				Note(aActor) != none ||
				AmbientSound(aActor) != none ||
				AIScript(aActor) != none ||
				xWeatherEffect(aActor) != none ||
				HUD(aActor) != none )
				continue;
 
			ActorList[ActorList.Length] = aActor;
		}
 
		// Search for a good cameralocation for max 2 seconds, after that, take whatever location we got
		SearchTimeLimit = Level.TimeSeconds + 2;
		while( Level.TimeSeconds < SearchTimeLimit )
		{
			// Pick a random actor to use as camera source
			aActor = ActorList[Rand(ActorList.Length)];
			CameraLocation = aActor.location;
 
			// Using static meshes as cameralocation can give very strange camerapositions
			if( StaticMeshActor(aActor) != none )
				continue;
 
			// Move out a randon number of units (atleast 256) from the light a random direction
			tmp = CameraLocation + VRand() * (rand(512) + 256);
 
			// Align new location to surrounding objects
			if( Trace( HitLoc, HitNormal, tmp, CameraLocation, true) != none )
				CameraLocation = hitloc + hitnormal * 64;
			else
				CameraLocation = tmp;
 
			// Try avoiding placing the camera inside an visible actor
			i = 0;
			foreach RadiusActors( class'Actor', aActor, 64, CameraLocation )
				if( aActor.bHidden == false ) i++;
			if( i > 0 )
				continue;
 
			// Make sure the area surrounding the camera is clear to reduce clipping artifacts
			if( (Trace( HitLoc, HitNormal, CameraLocation+vect(64,0,0), CameraLocation+vect(-64,0,0), true) == none) &&
				(Trace( HitLoc, HitNormal, CameraLocation+vect(0,64,0), CameraLocation+vect(0,-64,0), true) == none) &&
				(Trace( HitLoc, HitNormal, CameraLocation+vect(0,0,64), CameraLocation+vect(0,0,-64), true) == none) )
				break;
		}
 
		// Find a cameratarget location
		for(i=0; i < ActorList.Length; i++)
		{
			TargetLocation = ActorList[i].location;
			dist = VSize( CameraLocation - TargetLocation );
 
			// Move the location out so we don't look straight at the actor
			tmp = TargetLocation + vrand() * rand(dist);
 
			// Don't push the new location through walls
			if( Trace(HitLoc,HitNormal, tmp, TargetLocation, false) != none )
				TargetLocation = hitloc + HitNormal * 64;
			else
				TargetLocation = tmp;
 
			// Update new distance
			dist = VSize( CameraLocation - TargetLocation );
 
			// Test this location and see if we found one with a better camera distance
			if( (bestdist <= 800) || ( (dist > 800) && (dist < bestdist) &&
				(Trace(hitloc, hitnormal, TargetLocation, CameraLocation, false) == none )) )
			{
				bestdist = dist;
				best = TargetLocation;
			}
		}
		SetLocation( CameraLocation );
		SetRotation( rotator(best-CameraLocation) );
	}
 
	function Timer()
	{
		SetSpectatorCamera();
	}
 
	simulated function BeginState()
	{
		if( Level.NetMode != NM_DedicatedServer )
		{
			SetTimer(6, true);
			SetSpectatorCamera();	// Initial cameraposition
		}
	}
}