UDN
Search public documentation:
DevelopmentKitGemsCreatingActorSelectionBoxesOrBrackets
日本語訳
中国翻译
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
中国翻译
한국어
Interested in the Unreal Engine?
Visit the Unreal Technology site.
Looking for jobs and company info?
Check out the Epic games site.
Questions about support via UDN?
Contact the UDN Staff
UE3 Home > Unreal Development Kit Gems > Creating actor selection boxes or brackets
UE3 Home > User Interfaces & HUDs > Creating actor selection boxes or brackets
UE3 Home > User Interfaces & HUDs > Creating actor selection boxes or brackets
Creating actor selection boxes or brackets
Last tested against UDK Mar, 2011
PC and iOS compatible
Overview
GameInfo
class ASIGameInfo extends UTDeathMatch; defaultproperties { bUseClassicHUD=true HUDType=class'ASIHUD' }
Related topics
- Unrealscript Game Flow
- Getting Started Gameplay
- Gametype Technical Guide
- Mastering Unrealscript Baptism By Fire
- Basic Game Quick Start
HUDInterface
interface ASIHUDInterface;
if (PawnSubClass(Actor) != None || VehicleSubClass(Actor) != None || DroppedPickupSubClass(Actor) != None) { RenderActorSelection(Actor); }
if (ASIHUDInterface(Actor) != None) { RenderActorSelection(Actor, ASIHUDInterface(Actor)); }
Related topics
HUD
class ASIHUD extends UTHUD; event PostRender() { local Actor HitActor; local Vector HitLocation, HitNormal, EyeLocation; local Rotator EyeRotation; Super.PostRender(); // Ensure the player owner is set if (PlayerOwner != None) { // Retrieve the player camera location and rotation PlayerOwner.GetPlayerViewPoint(EyeLocation, EyeRotation); // Perform a trace to find what the player is looking at // Use trace actors so that we can ignore unimportant objects ForEach TraceActors ( class'Actor', HitActor, HitLocation, HitNormal, EyeLocation + Vector(EyeRotation) * PlayerOwner.InteractDistance, EyeLocation, Vect(1.f, 1.f, 1.f),, TRACEFLAG_Bullet ) { // If the hit actor is the player owner, the player owner's pawn or the hit actor isn't visible if (HitActor == PlayerOwner || HitActor == PlayerOwner.Pawn || !FastTrace(HitActor.Location, EyeLocation)) { // Ignore this hit actor continue; } // Render the actor selection here } } }
enum EActorBracketStyle { EABS_2DActorBrackets, EABS_3DActorBrackets, EABS_2DBox, EABS_3DBox, EABS_3DCircle }; var EActorBracketStyle ActorBracketStyle;
// Render the actor selection here // Test what rendering style we want switch (ActorBracketStyle) { case EABS_2DActorBrackets: RenderTwoDeeActorBrackets(HitActor, HUDInterface); break; case EABS_3DActorBrackets: RenderThreeDeeActorBrackets(HitActor, HUDInterface); break; case EABS_2DBox: RenderTwoDeeBox(HitActor, HUDInterface); break; case EABS_3DBox: RenderThreeDeeBox(HitActor, HUDInterface); break; case EABS_3DCircle: RenderThreeDeeCircle(HitActor, HUDInterface); break; default: break; }
Related topics
2D bounds calculation
function Box GetTwoDeeActorBoundingBox(Actor Actor) { local Box ComponentsBoundingBox, OutBox; local Vector BoundingBoxCoordinates[8]; local int i; Actor.GetComponentsBoundingBox(ComponentsBoundingBox); // Z1 // X1, Y1 BoundingBoxCoordinates[0].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[0].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[0].Z = ComponentsBoundingBox.Min.Z; BoundingBoxCoordinates[0] = Canvas.Project(BoundingBoxCoordinates[0]); // X2, Y1 BoundingBoxCoordinates[1].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[1].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[1].Z = ComponentsBoundingBox.Min.Z; BoundingBoxCoordinates[1] = Canvas.Project(BoundingBoxCoordinates[1]); // X1, Y2 BoundingBoxCoordinates[2].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[2].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[2].Z = ComponentsBoundingBox.Min.Z; BoundingBoxCoordinates[2] = Canvas.Project(BoundingBoxCoordinates[2]); // X2, Y2 BoundingBoxCoordinates[3].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[3].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[3].Z = ComponentsBoundingBox.Min.Z; BoundingBoxCoordinates[3] = Canvas.Project(BoundingBoxCoordinates[3]); // Z2 // X1, Y1 BoundingBoxCoordinates[4].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[4].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[4].Z = ComponentsBoundingBox.Max.Z; BoundingBoxCoordinates[4] = Canvas.Project(BoundingBoxCoordinates[4]); // X2, Y1 BoundingBoxCoordinates[5].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[5].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[5].Z = ComponentsBoundingBox.Max.Z; BoundingBoxCoordinates[5] = Canvas.Project(BoundingBoxCoordinates[5]); // X1, Y2 BoundingBoxCoordinates[6].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[6].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[6].Z = ComponentsBoundingBox.Max.Z; BoundingBoxCoordinates[6] = Canvas.Project(BoundingBoxCoordinates[6]); // X2, Y2 BoundingBoxCoordinates[7].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[7].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[7].Z = ComponentsBoundingBox.Max.Z; BoundingBoxCoordinates[7] = Canvas.Project(BoundingBoxCoordinates[7]); // Find the left, top, right and bottom coordinates OutBox.Min.X = Canvas.ClipX; OutBox.Min.Y = Canvas.ClipY; OutBox.Max.X = 0; OutBox.Max.Y = 0; // Iterate though the bounding box coordinates for (i = 0; i < ArrayCount(BoundingBoxCoordinates); ++i) { // Detect the smallest X coordinate if (OutBox.Min.X > BoundingBoxCoordinates[i].X) { OutBox.Min.X = BoundingBoxCoordinates[i].X; } // Detect the smallest Y coordinate if (OutBox.Min.Y > BoundingBoxCoordinates[i].Y) { OutBox.Min.Y = BoundingBoxCoordinates[i].Y; } // Detect the largest X coordinate if (OutBox.Max.X < BoundingBoxCoordinates[i].X) { OutBox.Max.X = BoundingBoxCoordinates[i].X; } // Detect the largest Y coordinate if (OutBox.Max.Y < BoundingBoxCoordinates[i].Y) { OutBox.Max.Y = BoundingBoxCoordinates[i].Y; } } return OutBox; }
Related topics
2D selection box
function RenderTwoDeeBox(Actor Actor, ASIHUDInterface HUDInterface) { local Box ActorBoundingBox; if (Canvas == None || Actor == None) { return; } ActorBoundingBox = GetTwoDeeActorBoundingBox(Actor); // Draw the actor brackets Canvas.SetDrawColor(255, 255, 255); // Top left position Canvas.SetPos(ActorBoundingBox.Min.X, ActorBoundingBox.Min.Y); // Draw the box Canvas.DrawBox ( (ActorBoundingBox.Max.X - ActorBoundingBox.Min.X), (ActorBoundingBox.Max.Y - ActorBoundingBox.Min.Y) ); }
2D selection brackets
function RenderTwoDeeActorBrackets(Actor Actor, ASIHUDInterface HUDInterface) { local Box ActorBoundingBox; local int ActualWidth, ActualHeight; if (Canvas == None || Actor == None) { return; } ActorBoundingBox = GetTwoDeeActorBoundingBox(Actor); // Calculate the width and height ActualWidth = (ActorBoundingBox.Max.X - ActorBoundingBox.Min.X) * 0.3f; ActualHeight = (ActorBoundingBox.Max.Y - ActorBoundingBox.Min.Y) * 0.3f; // Draw the actor brackets Canvas.SetDrawColor(255, 255, 255); // Top left Canvas.SetPos(ActorBoundingBox.Min.X, ActorBoundingBox.Min.Y); Canvas.DrawRect(ActualWidth, 2); Canvas.SetPos(ActorBoundingBox.Min.X, ActorBoundingBox.Min.Y); Canvas.DrawRect(2, ActualHeight); // Top right Canvas.SetPos(ActorBoundingBox.Max.X - ActualWidth - 2, ActorBoundingBox.Min.Y); Canvas.DrawRect(ActualWidth, 2); Canvas.SetPos(ActorBoundingBox.Max.X - 2, ActorBoundingBox.Min.Y); Canvas.DrawRect(2, ActualHeight); // Bottom left Canvas.SetPos(ActorBoundingBox.Min.X, ActorBoundingBox.Max.Y - 2); Canvas.DrawRect(ActualWidth, 2); Canvas.SetPos(ActorBoundingBox.Min.X, ActorBoundingBox.Max.Y - ActualHeight - 2); Canvas.DrawRect(2, Actualheight); // Bottom right Canvas.SetPos(ActorBoundingBox.Max.X - ActualWidth - 2, ActorBoundingBox.Max.Y - 2); Canvas.DrawRect(ActualWidth + 2, 2); Canvas.SetPos(ActorBoundingBox.Max.X - 2, ActorBoundingBox.Max.Y - ActualHeight - 2); Canvas.DrawRect(2, ActualHeight + 2); }
3D selection box
function RenderThreeDeeBox(Actor Actor, ASIHUDInterface HUDInterface) { local Box ComponentsBoundingBox; local Vector BoundingBoxCoordinates[8]; local int i; if (Actor == None) { return; } Actor.GetComponentsBoundingBox(ComponentsBoundingBox); // Z1 // X1, Y1 BoundingBoxCoordinates[0].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[0].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[0].Z = ComponentsBoundingBox.Min.Z; // X2, Y1 BoundingBoxCoordinates[1].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[1].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[1].Z = ComponentsBoundingBox.Min.Z; // X2, Y2 BoundingBoxCoordinates[2].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[2].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[2].Z = ComponentsBoundingBox.Min.Z; // X1, Y2 BoundingBoxCoordinates[3].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[3].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[3].Z = ComponentsBoundingBox.Min.Z; // Z2 // X1, Y1 BoundingBoxCoordinates[4].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[4].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[4].Z = ComponentsBoundingBox.Max.Z; // X2, Y1 BoundingBoxCoordinates[5].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[5].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[5].Z = ComponentsBoundingBox.Max.Z; // X2, Y2 BoundingBoxCoordinates[6].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[6].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[6].Z = ComponentsBoundingBox.Max.Z; // X1, Y2 BoundingBoxCoordinates[7].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[7].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[7].Z = ComponentsBoundingBox.Max.Z; for (i = 0; i < 4; ++i) { Draw3DLine(BoundingBoxCoordinates[i], BoundingBoxCoordinates[(i == 3) ? 0 : i + 1], class'HUD'.default.WhiteColor); } for (i = 4; i < 8; ++i) { Draw3DLine(BoundingBoxCoordinates[i], BoundingBoxCoordinates[(i == 7) ? 4 : i + 1], class'HUD'.default.WhiteColor); } for (i = 0; i < 4; ++i) { Draw3DLine(BoundingBoxCoordinates[i], BoundingBoxCoordinates[i + 4], class'HUD'.default.WhiteColor); } }
3D selection bracket
function RenderThreeDeeActorBrackets(Actor Actor, ASIHUDInterface HUDInterface) { local Box ComponentsBoundingBox; local Vector BoundingBoxCoordinates[8], InnerBoxCoordinates[8]; local int i; local float f; if (Actor == None) { return; } Actor.GetComponentsBoundingBox(ComponentsBoundingBox); // Z1 // X1, Y1 BoundingBoxCoordinates[0].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[0].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[0].Z = ComponentsBoundingBox.Min.Z; // X2, Y1 BoundingBoxCoordinates[1].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[1].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[1].Z = ComponentsBoundingBox.Min.Z; // X2, Y2 BoundingBoxCoordinates[2].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[2].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[2].Z = ComponentsBoundingBox.Min.Z; // X1, Y2 BoundingBoxCoordinates[3].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[3].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[3].Z = ComponentsBoundingBox.Min.Z; // Z2 // X1, Y1 BoundingBoxCoordinates[4].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[4].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[4].Z = ComponentsBoundingBox.Max.Z; // X2, Y1 BoundingBoxCoordinates[5].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[5].Y = ComponentsBoundingBox.Min.Y; BoundingBoxCoordinates[5].Z = ComponentsBoundingBox.Max.Z; // X2, Y2 BoundingBoxCoordinates[6].X = ComponentsBoundingBox.Max.X; BoundingBoxCoordinates[6].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[6].Z = ComponentsBoundingBox.Max.Z; // X1, Y2 BoundingBoxCoordinates[7].X = ComponentsBoundingBox.Min.X; BoundingBoxCoordinates[7].Y = ComponentsBoundingBox.Max.Y; BoundingBoxCoordinates[7].Z = ComponentsBoundingBox.Max.Z; // Calc inner X f = VSize(BoundingBoxCoordinates[4] - BoundingBoxCoordinates[5]) * 0.3f; // Z1 // X1, Y1 InnerBoxCoordinates[0].X = ComponentsBoundingBox.Min.X + f; InnerBoxCoordinates[0].Y = ComponentsBoundingBox.Min.Y; InnerBoxCoordinates[0].Z = ComponentsBoundingBox.Min.Z; // X2, Y1 InnerBoxCoordinates[1].X = ComponentsBoundingBox.Max.X - f; InnerBoxCoordinates[1].Y = ComponentsBoundingBox.Min.Y; InnerBoxCoordinates[1].Z = ComponentsBoundingBox.Min.Z; // X2, Y2 InnerBoxCoordinates[2].X = ComponentsBoundingBox.Max.X - f; InnerBoxCoordinates[2].Y = ComponentsBoundingBox.Max.Y; InnerBoxCoordinates[2].Z = ComponentsBoundingBox.Min.Z; // X1, Y2 InnerBoxCoordinates[3].X = ComponentsBoundingBox.Min.X + f; InnerBoxCoordinates[3].Y = ComponentsBoundingBox.Max.Y; InnerBoxCoordinates[3].Z = ComponentsBoundingBox.Min.Z; // Z2 // X1, Y1 InnerBoxCoordinates[4].X = ComponentsBoundingBox.Min.X + f; InnerBoxCoordinates[4].Y = ComponentsBoundingBox.Min.Y; InnerBoxCoordinates[4].Z = ComponentsBoundingBox.Max.Z; // X2, Y1 InnerBoxCoordinates[5].X = ComponentsBoundingBox.Max.X - f; InnerBoxCoordinates[5].Y = ComponentsBoundingBox.Min.Y; InnerBoxCoordinates[5].Z = ComponentsBoundingBox.Max.Z; // X2, Y2 InnerBoxCoordinates[6].X = ComponentsBoundingBox.Max.X - f; InnerBoxCoordinates[6].Y = ComponentsBoundingBox.Max.Y; InnerBoxCoordinates[6].Z = ComponentsBoundingBox.Max.Z; // X1, Y2 InnerBoxCoordinates[7].X = ComponentsBoundingBox.Min.X + f; InnerBoxCoordinates[7].Y = ComponentsBoundingBox.Max.Y; InnerBoxCoordinates[7].Z = ComponentsBoundingBox.Max.Z; for (i = 0; i < 8; ++i) { Draw3DLine(BoundingBoxCoordinates[i], InnerBoxCoordinates[i], class'HUD'.default.WhiteColor); } // Calc inner Y f = VSize(BoundingBoxCoordinates[4] - BoundingBoxCoordinates[7]) * 0.3f; // Z1 // X1, Y1 InnerBoxCoordinates[0].X = ComponentsBoundingBox.Min.X; InnerBoxCoordinates[0].Y = ComponentsBoundingBox.Min.Y + f; InnerBoxCoordinates[0].Z = ComponentsBoundingBox.Min.Z; // X2, Y1 InnerBoxCoordinates[1].X = ComponentsBoundingBox.Max.X; InnerBoxCoordinates[1].Y = ComponentsBoundingBox.Min.Y + f; InnerBoxCoordinates[1].Z = ComponentsBoundingBox.Min.Z; // X2, Y2 InnerBoxCoordinates[2].X = ComponentsBoundingBox.Max.X; InnerBoxCoordinates[2].Y = ComponentsBoundingBox.Max.Y - f; InnerBoxCoordinates[2].Z = ComponentsBoundingBox.Min.Z; // X1, Y2 InnerBoxCoordinates[3].X = ComponentsBoundingBox.Min.X; InnerBoxCoordinates[3].Y = ComponentsBoundingBox.Max.Y - f; InnerBoxCoordinates[3].Z = ComponentsBoundingBox.Min.Z; // Z2 // X1, Y1 InnerBoxCoordinates[4].X = ComponentsBoundingBox.Min.X; InnerBoxCoordinates[4].Y = ComponentsBoundingBox.Min.Y + f; InnerBoxCoordinates[4].Z = ComponentsBoundingBox.Max.Z; // X2, Y1 InnerBoxCoordinates[5].X = ComponentsBoundingBox.Max.X; InnerBoxCoordinates[5].Y = ComponentsBoundingBox.Min.Y + f; InnerBoxCoordinates[5].Z = ComponentsBoundingBox.Max.Z; // X2, Y2 InnerBoxCoordinates[6].X = ComponentsBoundingBox.Max.X; InnerBoxCoordinates[6].Y = ComponentsBoundingBox.Max.Y - f; InnerBoxCoordinates[6].Z = ComponentsBoundingBox.Max.Z; // X1, Y2 InnerBoxCoordinates[7].X = ComponentsBoundingBox.Min.X; InnerBoxCoordinates[7].Y = ComponentsBoundingBox.Max.Y - f; InnerBoxCoordinates[7].Z = ComponentsBoundingBox.Max.Z; for (i = 0; i < 8; ++i) { Draw3DLine(BoundingBoxCoordinates[i], InnerBoxCoordinates[i], class'HUD'.default.WhiteColor); } // Calc inner Z f = VSize(BoundingBoxCoordinates[0] - BoundingBoxCoordinates[4]) * 0.3f; // Z1 // X1, Y1 InnerBoxCoordinates[0].X = ComponentsBoundingBox.Min.X; InnerBoxCoordinates[0].Y = ComponentsBoundingBox.Min.Y; InnerBoxCoordinates[0].Z = ComponentsBoundingBox.Min.Z + f; // X2, Y1 InnerBoxCoordinates[1].X = ComponentsBoundingBox.Max.X; InnerBoxCoordinates[1].Y = ComponentsBoundingBox.Min.Y; InnerBoxCoordinates[1].Z = ComponentsBoundingBox.Min.Z + f; // X2, Y2 InnerBoxCoordinates[2].X = ComponentsBoundingBox.Max.X; InnerBoxCoordinates[2].Y = ComponentsBoundingBox.Max.Y; InnerBoxCoordinates[2].Z = ComponentsBoundingBox.Min.Z + f; // X1, Y2 InnerBoxCoordinates[3].X = ComponentsBoundingBox.Min.X; InnerBoxCoordinates[3].Y = ComponentsBoundingBox.Max.Y; InnerBoxCoordinates[3].Z = ComponentsBoundingBox.Min.Z + f; // Z2 // X1, Y1 InnerBoxCoordinates[4].X = ComponentsBoundingBox.Min.X; InnerBoxCoordinates[4].Y = ComponentsBoundingBox.Min.Y; InnerBoxCoordinates[4].Z = ComponentsBoundingBox.Max.Z - f; // X2, Y1 InnerBoxCoordinates[5].X = ComponentsBoundingBox.Max.X; InnerBoxCoordinates[5].Y = ComponentsBoundingBox.Min.Y; InnerBoxCoordinates[5].Z = ComponentsBoundingBox.Max.Z - f; // X2, Y2 InnerBoxCoordinates[6].X = ComponentsBoundingBox.Max.X; InnerBoxCoordinates[6].Y = ComponentsBoundingBox.Max.Y; InnerBoxCoordinates[6].Z = ComponentsBoundingBox.Max.Z - f; // X1, Y2 InnerBoxCoordinates[7].X = ComponentsBoundingBox.Min.X; InnerBoxCoordinates[7].Y = ComponentsBoundingBox.Max.Y; InnerBoxCoordinates[7].Z = ComponentsBoundingBox.Max.Z - f; for (i = 0; i < 8; ++i) { Draw3DLine(BoundingBoxCoordinates[i], InnerBoxCoordinates[i], class'HUD'.default.WhiteColor); } }
3D selection circle
function RenderThreeDeeCircle(Actor Actor, ASIHUDInterface HUDInterface) { local Rotator Angle; local Vector Radius, Offsets[16]; local Box ComponentsBoundingBox; local float Width, Height; local int i; if (Actor == None) { return; } Actor.GetComponentsBoundingBox(ComponentsBoundingBox); Width = ComponentsBoundingBox.Max.X - ComponentsBoundingBox.Min.X; Height = ComponentsBoundingBox.Max.Y - ComponentsBoundingBox.Min.Y; Radius.X = (Width > Height) ? Width : Height; i = 0; for (Angle.Yaw = 0; Angle.Yaw < 65536; Angle.Yaw += 4096) { // Calculate the offset Offsets[i] = Actor.Location + (Radius >> Angle) + Vect(0.f, 0.f, 16.f); i++; } // Draw all of the lines for (i = 0; i < ArrayCount(Offsets); ++i) { if (i == ArrayCount(Offsets) - 1) { Draw3DLine(Offsets[i], Offsets[0], class'HUD'.default.WhiteColor); } else { Draw3DLine(Offsets[i], Offsets[i + 1], class'HUD'.default.WhiteColor); } } }
Testing
Related topics
Downloads
- Download the unrealscript code. (ActorSelectionInterface.zip)