My program doesn't have bugs. It just develops random features.
Legacy:Wizzie/OnJoinSpectatorCamera
From Unreal Wiki, The Unreal Engine Documentation Site
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
}
}
}
