UDN
Search public documentation:
BasicGameQuickStartKR
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
기본 게임 퀵스타트
개요
프로젝트 셋업
언리얼스크립트 프로젝트
어느 게임 프로젝트건 결국 게임플레이를 이루기 위한 커스텀 클래스를 만들기 위해서는 언리얼스크립트를 필요로 하게 됩니다. 새 언리얼스크립트를 추가하려면 스크립트를 담기 위한 커스텀 UnrealScript 프로젝트를 구성해야 하며, 이것이 새로운 UnrealScript (.u 파일) 패키지 속으로 컴파일되는 것입니다. UnrealScript 프로젝트를 만들려면 먼저 언리얼 설치 디렉토리의..\Development\Src
디렉토리를 찾습니다. 이 디렉토리 안에 프로젝트에 지을 이름으로 된 폴더를 새로 만듭니다. 보통 만들려는 게임의 약자에 "Game" 을 붙이곤 합니다. 예를 들어 Unreal Tournament 게임이라면 UTGame
정도가 됩니다.
여기에 생성되는 예제 게임에서, UnrealScript 프로젝트의 이름은 UDNGame
으로 하겠습니다. 이 새 폴더의 위치는 생성되고나면 ..\Developement\Src
내에 있게 됩니다:

UDNGame
폴더 안에 Classes
라는 이름의 새 폴더가 생성됩니다. 여기에 프로젝트용 스크립트가 담기게 됩니다.

Content 디렉토리
콘텐츠 없는 게임이 어디 게임일까요. 화면상에 표시할 시각 요소가, 재생할 소리가 있어야 합니다. 물론 콘텐츠를 모두 꾸려넣고 플레이어에게 보여줄 맵도 있어야죠. 일반적으로 패키지 내에 저장된 콘텐츠는 (맵도 패키지입니다) 그 자체적으로 언리얼 설치 디렉토리의..\[GameName]\Content
디렉토리에 저장됩니다. Content
디렉토리에는 보통 Characters
, Environments
, Maps
, Sounds
등의 폴더가 있는데, 이를 통해 콘텐츠 패키지와 맵을 조직적으로 관리할 수 있습니다.
UDK를 사용할 때, 이 서브 폴더에는 예제 콘텐츠가 채워져 있습니다. 그냥 아주 쉽게 게임의 커스텀 콘텐츠 패지지와 맵을 똑같은 폴더에 저장하기만 해도 모든것이 완벽하게 잘 돌아갈 것입니다. 그러나 커스텀 콘텐츠와 다른 콘텐츠를 따로 관리하고 싶다면, 그냥 Content
디렉토리에 새 폴더를, 그저 별개의 이름으로 만들어 주고, 그 폴더에 패키지를 저장하면 됩니다. 심지어 그 안에다가도 폴더를 추가로 만들어, Content
디렉토리에서와 유사한 방식으로 패키지를 관리할 수 있습니다.
게임플레이 클래스
Camera
어느 게임이든 가장 핵심적인 요소 중 하나는 플레이어가 세상을 바라보는 관점입니다. 언리얼에서 플레이어 시점의 위치와 방향은PlayerController
클래스의 GetPlayerViewPoint()
함수에서 처리됩니다. 디폴트로 플레이어 카메라 오브젝트가 있다면, 계산을 처리하도록 허용된 것입니다. 위치와 방향을 계산하는 데는 두 방법 중 하나를 쓸 수 있습니다:
-
UpdateCamera()
함수에서Pawn
에 있는CalcCamera()
를 호출 -
UpdateCamera()
함수에서 시점을 직접 계산
CalcCamera()
함수를 사용하여 Pawn
클래스에서 구현할 수도 있으나, 카메라 로직을 별도의 클래스에 캡슐화시켜 유지하고자 함은 물론, 카메라 클래스를 사용하면 포스트 프로세싱이나 카메라 애니메이션과 같은 카메라 기능 전부를 접근할 수 있다는 사실 때문에라도, 우리 예제에서는 카메라의 위치를 처리하는 데 커스텀 Camera
클래스를 사용할 것입니다. 이 예제가 비록 3인칭 시점이기는 하나, 카메라 위치와 회전을 계산하는 로직만 바꿔주면 쉽게 다른 종류의 카메라도 구현할 수 있습니다.
Camera Technical Guide KR 페이지에서 카메라에 대한 세부적인 설명은 물론, 다른 시점 구현에 대한 예제도 살펴볼 수 있습니다.
class UDNPlayerCamera extends Camera; var Vector CamOffset; var float CameraZOffset; var float CameraScale, CurrentCameraScale; /** 디폴트 카메라 거리에의 곱수 */ var float CameraScaleMin, CameraScaleMax; function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime) { local vector HitLocation, HitNormal; local CameraActor CamActor; local Pawn TPawn; local vector CamStart, CamDirX, CamDirY, CamDirZ, CurrentCamOffset; local float DesiredCameraZOffset; // 보간 도중 나가는 뷰타겟 업데이트 중지 if( PendingViewTarget.Target != None && OutVT == ViewTarget && BlendParams.bLockOutgoing ) { return; } // 뷰타겟 상의 디폴트 FOV OutVT.POV.FOV = DefaultFOV; // 카메라 액터를 통해 보기 CamActor = CameraActor(OutVT.Target); if( CamActor != None ) { CamActor.GetCameraView(DeltaTime, OutVT.POV); // CameraActor 로부터 상 비율 획득 bConstrainAspectRatio = bConstrainAspectRatio || CamActor.bConstrainAspectRatio; OutVT.AspectRatio = CamActor.AspectRatio; // CameraActor 가 사용된 PostProcess 세팅을 덮어쓰려 하는지 확인 CamOverridePostProcessAlpha = CamActor.CamOverridePostProcessAlpha; CamPostProcessSettings = CamActor.CamOverridePostProcess; } else { TPawn = Pawn(OutVT.Target); // Pawn ViewTarget 에 카메라 위치를 불러줄 기회를 줍니다. // Pawn 이 카메라 뷰를 덮어쓰지 않는다면, 자체 디폴트를 가지고 진행 if( TPawn == None || !TPawn.CalcCamera(DeltaTime, OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV) ) { /************************************** * 3인칭 시점 계산 * UTPawn 구현 차용 **************************************/ OutVT.POV.Rotation = PCOwner.Rotation; CamStart = TPawn.Location; CurrentCamOffset = CamOffset; DesiredCameraZOffset = 1.2 * TPawn.GetCollisionHeight() + TPawn.Mesh.Translation.Z; CameraZOffset = (DeltaTime < 0.2) ? DesiredCameraZOffset * 5 * DeltaTime + (1 - 5*DeltaTime) * CameraZOffset : DesiredCameraZOffset; CamStart.Z += CameraZOffset; GetAxes(OutVT.POV.Rotation, CamDirX, CamDirY, CamDirZ); CamDirX *= CurrentCameraScale; TPawn.FindSpot(Tpawn.GetCollisionExtent(),CamStart); if (CurrentCameraScale < CameraScale) { CurrentCameraScale = FMin(CameraScale, CurrentCameraScale + 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*DeltaTime); } else if (CurrentCameraScale > CameraScale) { CurrentCameraScale = FMax(CameraScale, CurrentCameraScale - 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*DeltaTime); } if (CamDirX.Z > TPawn.GetCollisionHeight()) { CamDirX *= square(cos(OutVT.POV.Rotation.Pitch * 0.0000958738)); // 0.0000958738 = 2*PI/65536 } OutVT.POV.Location = CamStart - CamDirX*CurrentCamOffset.X + CurrentCamOffset.Y*CamDirY + CurrentCamOffset.Z*CamDirZ; if (Trace(HitLocation, HitNormal, OutVT.POV.Location, CamStart, false, vect(12,12,12)) != None) { OutVT.POV.Location = HitLocation; } } } // Apply camera modifiers at the end (view shakes for example) ApplyCameraModifiers(DeltaTime, OutVT.POV); } defaultproperties { CamOffset=(X=12.0,Y=0.0,Z=-13.0) CurrentCameraScale=1.0 CameraScale=9.0 CameraScaleMin=3.0 CameraScaleMax=40.0 }
PlayerController
어느 게임이고 또다른 중요 요소는 플레이어의 입력을 어떻게 처리할 것인지, 게임 제어로 어떻게 옮길 것인지, 화면상의 메인 캐릭터를 직접 조종할 것인지, 포인트-앤-클릭 인터페이스를 사용할 것인지 다른 방식을 사용할 것인지를 정하는 것입니다. 꽤나 직관적이게도, 플레이어가 게임을 콘트롤하는 방식을 결정하는 것을 담당하는 클래스 이름은PlayerController
입니다.
베이스 PlayerController
구현은 플레이어 입력을 받아 이동으로 옮겨 주기에 플레이어를 뛰어다니게 하는 데는 충분합니다. 예제에서 사용된 커스텀 PlayerController
클래스는 단지 위에서 만든 커스텀 Camera
클래스를 할당해 주는 것입니다. 물론 게임에 살을 붙여가면서, 말할 것도 없니 이 클래스에 변경을 가하고 게임 특정 구현에 필요한 로직을 추가시키고 해야 할 것입니다.
Characters Technical Guide KR 페이지에서 PlayerController
클래스에 대한 세부적인 설명과, 새로운 유형의 게임에 맞도록 특화시키는 법을 찾아보실 수 있습니다.
class UDNPlayerController extends GamePlayerController; defaultproperties { CameraClass=class'UDNGame.UDNPlayerCamera' }
Pawn
PlayerController
클래스는 게임을 제어하는 데 플레이어 입력을 어떻게 처리하는지, 즉 이 예제에서는 직접 캐릭터를 움직이도록 하는 역할을 하고 있으나, 캐릭터에 대한 시각적인 표현 및 그것이 물리 세계와 상호작용하는 방식을 결정하기 위한 로직은 Pawn
클래스에 캡슐화되어 있습니다. 이 예제의 커스텀 Pawn
클래스에는 환경과 상호작용하기 위한 특수 로직은 추가하지 않을 것이나, 캐릭터의 시각적 표현 구성을 담당하게 될 것입니다. 즉 게임의 캐릭터를 표시하는 데 사용되는 스켈레탈 메시, 애니메이션, 피직스 애셋을 설정한다는 뜻입니다.
Characters Technical Guide KR 페이지에서 Pawn
클래스의 세부적인 설명 및 Pawn
클래스가 PlayerController
클래스와 협업하는 방법에 대해 확인해 보실 수 있습니다.
class UDNPawn extends Pawn; var DynamicLightEnvironmentComponent LightEnvironment; defaultproperties { WalkingPct=+0.4 CrouchedPct=+0.4 BaseEyeHeight=38.0 EyeHeight=38.0 GroundSpeed=440.0 AirSpeed=440.0 WaterSpeed=220.0 AccelRate=2048.0 JumpZ=322.0 CrouchHeight=29.0 CrouchRadius=21.0 WalkableFloorZ=0.78 Components.Remove(Sprite) Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment bSynthesizeSHLight=TRUE bIsCharacterLightEnvironment=TRUE bUseBooleanEnvironmentShadowing=FALSE End Object Components.Add(MyLightEnvironment) LightEnvironment=MyLightEnvironment Begin Object Class=SkeletalMeshComponent Name=WPawnSkeletalMeshComponent //내 메시 프로퍼티 SkeletalMesh=SkeletalMesh'CH_LIAM_Cathode.Mesh.SK_CH_LIAM_Cathode' AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human' PhysicsAsset=PhysicsAsset'CH_AnimCorrupt.Mesh.SK_CH_Corrupt_Male_Physics' AnimSets(0)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale' Translation=(Z=8.0) Scale=1.075 //일반 메시 프로퍼티 bCacheAnimSequenceNodes=FALSE AlwaysLoadOnClient=true AlwaysLoadOnServer=true bOwnerNoSee=false CastShadow=true BlockRigidBody=TRUE bUpdateSkelWhenNotRendered=false bIgnoreControllersWhenNotRendered=TRUE bUpdateKinematicBonesFromAnimation=true bCastDynamicShadow=true RBChannel=RBCC_Untitled3 RBCollideWithChannels=(Untitled3=true) LightEnvironment=MyLightEnvironment bOverrideAttachmentOwnerVisibility=true bAcceptsDynamicDecals=FALSE bHasPhysicsAssetInstance=true TickGroup=TG_PreAsyncWork MinDistFactorForKinematicUpdate=0.2 bChartDistanceFactor=true RBDominanceGroup=20 bUseOnePassLightingOnTranslucency=TRUE bPerBoneMotionBlur=true End Object Mesh=WPawnSkeletalMeshComponent Components.Add(WPawnSkeletalMeshComponent) Begin Object Name=CollisionCylinder CollisionRadius=+0021.000000 CollisionHeight=+0044.000000 End Object CylinderComponent=CollisionCylinder }
HUD
HUD
클래스는 게임에 대한 정보를 플레이어에게 표시해 주는 것을 담당하는 클래스입니다. 표시되는 정보와 그 방식은 게임에 따라 매우 다릅니다. 그렇기에 예제 구현에서는 Canvas
오브젝트 또는 스케일폼 GFx 자체 커스텀 HUD를 만들 수 있도록 검정 석판을 제공해 보겠습니다.
HUD Technical Guide KR 페이지에서 Canvas
오브젝트나 언리얼 엔진 3의 스케일폼 GFx 통합을 둘 다 사용하여 HUD 를 만드는 법에 대한 세부 정보를 확인할 수 있습니다.
class UDNHUD extends MobileHUD; defaultproperties { }
Gametype
게임타입은 게임의 심장입니다. 게임의 규칙과 게임의 진행을 계속시킬지 말지를 결정하는 조건을 확정합니다. 확실히 이는 전적으로 게임-전용입니다. 게임타입은PlayerControllers
, Pawns
, HUD
등에 대해 어떤 클래스를 사용할 지 엔진에 알려주는 역할을 하기도 합니다. 게임타입의 예제 구현은 단지 defaultproperties
안에 이 클래스를 지정하고, 나머지 구현은 당신께 맡기는 것입니다.
Gametype Technical Guide KR 페이지에서 게임타입에 대한 깊이있는 개념 설명과, 커스텀 게임타입에 맞도록 어느 부분을 커스터마이징해야할 지에 대한 통찰을 얻을 수 있을 것입니다.
class UDNGame extends FrameworkGame; defaultproperties { PlayerControllerClass=class'UDNGame.UDNPlayerController' DefaultPawnClass=class'UDNGame.UDNPawn' HUDType=class'UDNGame.UDNHUD' bDelayedStart=false }
컴파일하기

DefaultEngine.ini
의 [UInrealEd.EditorEngine]
부분에 있는 EditPackages
배열에 프로젝트를 추가하면 됩니다. UDNGame
프로젝트 추가를 위한 구문은 다음과 같습니다.
+EditPackages=UDNGame
UTGame
이나 UTGameContent
프로젝트같은 것 말입니다. 이 프로젝트는 지우려는데, 이들은 UDK에 제공된 UT3 예제 게임일 뿐이고, 다시 강조하지만 이 예제에서의 개념은 귀하의 게임에 사용할 수 있는 베어본 프레임워크를 만들고자 함이기 때문입니다. 만들려는 게임이 UT 게임과 유샤하다면, 그 프로젝트들은 놔두고 거기서 클래스 제작을 시작해야 할 것입니다. 그것은 전적으로 만들려 하는 게임의 종류에 따라 결정내릴 사안인 것입니다. [UnrealEd.EditorEngine]
부분의 최종적인 모습은 이와 같을 것입니다:
[UnrealEd.EditorEngine] +EditPackages=UTGame +EditPackages=UTGameContent +EditPackages=UDNGame
-
Make
커맨드릿 실행 - UnrealFrontend 를 통해 실행
- 게임이나 에디터 실행



테스트하기
- 언리얼 에디터 내 테스트 맵의
WorldInfo
프로퍼티에서 PIE Gametype 을UDNGame
으로 설정 -
DefaultGame.ini
환경설정 파일 안에 엔진의 기본 게임타입을UDNGame
으로 설정
UDNGame
게임타입을 언리얼 에디터나 엔진에서 플레이할 때 특정 맵에 사용되는 게임타입으로 설정하려면, 보기 메뉴에서 월드 프로퍼티 를 선택합니다. WorldInfo
프로퍼티창이 표시될 것입니다.

Gametype for PIE
프로퍼티를 찾습니다. 사용가능한 게임타입 목록에서 UDNGame
을 선택합니다.


UDNGame
으로 설정하여, 이 맵이 (아래 설명된) .ini 파일의 디폴트 세팅에 관계없이 강제로 커스텀 게임타입을 사용하도록 할 수 있습니다.
Default Gametype
주: .ini 파일을 편집할 때는 에디터가 닫혀 있어야 합니다.
엔진의 디폴트 게임타입으로 UDNGame
게임타입을 설정하려면, 언리얼 설치 디렉토리 아래의 ..\[GameName]\Config
에 있는 Defaultgame.ini
환경설정 파일을 엽니다. 여기에 지정하면, 맵에 대한 게임타입 접두사가 없거나 맵에 지정된 게임타입이 없을 때 이 게임타입이 사용됩니다. [Engine.GameInfo]
부분에는 UDNGame
게임타입에 할당할 수 있는 프로퍼티가 셋 있습니다. PlayerController
클래스에 할당할 수 있는 프로퍼티도 있습니다. 마지막으로 곧 지울 UT3 예제 게임에 대해서만 사용되는 게임타입 접두사 구성용 줄도 몇 있습니다.
[Engine.GameInfo]
부분의 최종적인 모습은 이와 같습니다:
[Engine.GameInfo] DefaultGame=UDNGame.UDNGame DefaultServerGame=UDNGame.UDNGame PlayerControllerClassName=UDNGame.UDNPlayerController GameDifficulty=+1.0 MaxPlayers=32 DefaultGameType="UDNGame.UDNGame"
