UDN
Search public documentation:
DevelopmentKitGemsCreatingActorSelectionBoxesOrBracketsKR
English Translation
日本語訳
中国翻译
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
액터 선택 박스나 브래킷 만들기
문서 변경내역: James Tan 작성. 홍성진 번역.
UDK 2011년 3월 버전으로 최종 테스팅, PC 와 iOS 호환
개요
GameInfo
class ASIGameInfo extends UTDeathMatch;
defaultproperties
{
bUseClassicHUD=true
HUDType=class'ASIHUD'
}
관련 토픽
- UnrealScript Game Flow KR
- Getting Started Gameplay KR
- Gametype Technical Guide KR
- Mastering UnrealScript Baptism By Fire KR
- Basic Game Quick Start KR
HUDInterface
interface ASIHUDInterface;
if (PawnSubClass(Actor) != None || VehicleSubClass(Actor) != None || DroppedPickupSubClass(Actor) != None)
{
RenderActorSelection(Actor);
}
if (ASIHUDInterface(Actor) != None)
{
RenderActorSelection(Actor, ASIHUDInterface(Actor));
}
관련 토픽
HUD
class ASIHUD extends UTHUD;
event PostRender()
{
local Actor HitActor;
local Vector HitLocation, HitNormal, EyeLocation;
local Rotator EyeRotation;
Super.PostRender();
// player owner 가 설정되었는지 확인
if (PlayerOwner != None)
{
// 플레이어 카메라 위치 및 회전 구하기
PlayerOwner.GetPlayerViewPoint(EyeLocation, EyeRotation);
// 플레이어가 바라보는 것을 찾기 위해 trace 수행
// 중요치 않은 오브젝트를 무시할 수 있도록 trace 액터 사용
ForEach TraceActors
(
class'Actor',
HitActor,
HitLocation,
HitNormal,
EyeLocation + Vector(EyeRotation) * PlayerOwner.InteractDistance,
EyeLocation,
Vect(1.f, 1.f, 1.f),,
TRACEFLAG_Bullet
)
{
// hit actor 가 player owner 라면, player owner 의 pawn 또는 hit actor 는 안보임
if (HitActor == PlayerOwner || HitActor == PlayerOwner.Pawn || !FastTrace(HitActor.Location, EyeLocation))
{
// 이 hit actor 무시
continue;
}
// 여기에 액터 선택 렌더링
}
}
}
enum EActorBracketStyle
{
EABS_2DActorBrackets,
EABS_3DActorBrackets,
EABS_2DBox,
EABS_3DBox,
EABS_3DCircle
};
var EActorBracketStyle ActorBracketStyle;
// 여기 액터 선택을 렌더링
// 원하는 렌더링 스타일 테스트
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;
}
관련 토픽
2D 경계 계산
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]);
// 좌 상 우 하 좌표 찾기
OutBox.Min.X = Canvas.ClipX;
OutBox.Min.Y = Canvas.ClipY;
OutBox.Max.X = 0;
OutBox.Max.Y = 0;
// 경계 박스 좌표를 통해 반복처리
for (i = 0; i < ArrayCount(BoundingBoxCoordinates); ++i)
{
// 가장 작은 X 좌표 검출
if (OutBox.Min.X > BoundingBoxCoordinates[i].X)
{
OutBox.Min.X = BoundingBoxCoordinates[i].X;
}
// 가장 작은 Y 좌표 검출
if (OutBox.Min.Y > BoundingBoxCoordinates[i].Y)
{
OutBox.Min.Y = BoundingBoxCoordinates[i].Y;
}
// 가장 큰 X 좌표 검출
if (OutBox.Max.X < BoundingBoxCoordinates[i].X)
{
OutBox.Max.X = BoundingBoxCoordinates[i].X;
}
// 가장 큰 Y 좌표 검출
if (OutBox.Max.Y < BoundingBoxCoordinates[i].Y)
{
OutBox.Max.Y = BoundingBoxCoordinates[i].Y;
}
}
return OutBox;
}
관련 토픽
2D 선택 박스
이 스타일을 렌더링하기 위해, 액터 컴포넌트 경계 박스가 캔버스 공간으로 투영됩니다. 거기서 단순히, 투영된 경계 박스를 나타내는 박스가 렌더링됩니다.
function RenderTwoDeeBox(Actor Actor, ASIHUDInterface HUDInterface)
{
local Box ActorBoundingBox;
if (Canvas == None || Actor == None)
{
return;
}
ActorBoundingBox = GetTwoDeeActorBoundingBox(Actor);
// 액터 브래킷 그리기
Canvas.SetDrawColor(255, 255, 255);
// 좌상단 위치
Canvas.SetPos(ActorBoundingBox.Min.X, ActorBoundingBox.Min.Y);
// 박스 그리기
Canvas.DrawBox
(
(ActorBoundingBox.Max.X - ActorBoundingBox.Min.X),
(ActorBoundingBox.Max.Y - ActorBoundingBox.Min.Y)
);
}
2D 선택 브래킷
이 스타일을 렌더링하기 위해, 액터 컴포넌트 경계 박스가 캔버스 공간 상에 투영됩니다. 거기서 브래킷의 각 코너가 렌더링됩니다.
function RenderTwoDeeActorBrackets(Actor Actor, ASIHUDInterface HUDInterface)
{
local Box ActorBoundingBox;
local int ActualWidth, ActualHeight;
if (Canvas == None || Actor == None)
{
return;
}
ActorBoundingBox = GetTwoDeeActorBoundingBox(Actor);
// 폭과 높이 계산
ActualWidth = (ActorBoundingBox.Max.X - ActorBoundingBox.Min.X) * 0.3f;
ActualHeight = (ActorBoundingBox.Max.Y - ActorBoundingBox.Min.Y) * 0.3f;
// 액터 브래킷 그리기
Canvas.SetDrawColor(255, 255, 255);
// 좌상단
Canvas.SetPos(ActorBoundingBox.Min.X, ActorBoundingBox.Min.Y);
Canvas.DrawRect(ActualWidth, 2);
Canvas.SetPos(ActorBoundingBox.Min.X, ActorBoundingBox.Min.Y);
Canvas.DrawRect(2, ActualHeight);
// 우상단
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);
// 좌하단
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);
// 우하단
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 선택 박스
3D 선택 박스를 렌더링하기 위해, 여기서는 HUD 내 Draw3DLine 함수가 사용되었습니다. 이 함수는 폭이 1 픽셀인 선만 그릴 수 있다는 제한이 있습니다. 이 제한을 고치려면, 각 경계 박스 좌표를 캔버스 공간으로 투영한 다음 2D 선을 대신 그립니다.
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 선택 브래킷
3D 브래킷 선택 박스를 렌더링하기 위해, HUD 내 Draw3DLine 함수가 사용되었습니다. 다시금 이 제한은 화면 공간에 필수 좌표 전부를 투영하고서 2D 선을 그려 제한을 고칠 수 있습니다. 이 선택 스타일을 렌더링하려면 먼저 내부 좌표를 계산한 다음 선을 그립니다.
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;
// 내부 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);
}
// 내부 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);
}
// 내부 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 선택 원
이 선택 스타일은 HUD 내 Draw3DLine 함수를 사용합니다. 모든 오프셋을 캔버스 좌표 속으로 투영한 다음 2D 선을 그리는 것도 가능합니다. 모든 오프셋은 벡터의 Z 성분을 늘려 조절했습니다. 이를 통해 원을 위쪽으로 올릴 수 있습니다. 다른 벡터 오프셋을 추가하여 원의 위치를 옮길 수 있습니다. 원 내의 점 수를 늘리려면, 계산되는 점의 수를 조절해야 합니다. 언리얼 회전 단위(현재 4096)로 yaw 증감값을 늘리거나 줄이면 됩니다. 오프셋 배열의 크기도 (현재 65536/4096, 16인) yaw 증감값에 일치시키기 위해 늘려야 합니다.
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)
{
// 오프셋 계산
Offsets[i] = Actor.Location + (Radius >> Angle) + Vect(0.f, 0.f, 16.f);
i++;
}
// 모든 라인 그리기
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);
}
}
}
테스팅
관련 토픽
다운로드
- ActorSelectionInterface.zip 내려받기: 언리얼스크립트 코드입니다.
