UDN
Search public documentation:

MyFirstPawnKR
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

예제: My First Pawn

2003년 11월 7일, 2226 빌드용으로 Chris Linder (DemiurgeStudios?) 작성. 업데이트 Chris Linder (DemiurgeStudios?). 최종 업데이트 Michiel Hendriks - 3323를 위해 애니메이션 코드 변경.

관련 문서

My First Code, My First Controller, My First GameInfo, My First HUD

서론

My First Code 문서를 아직 읽지 않으셨다면 먼저 그것을 읽으십시오.

이 문서에서는 세계에서 돌아다니는 간단한 pawn 클래스를 작성하는 법과 올바르게 애니메이트하는 방법을 살펴봅니다. 올바르게 애니메이트한다는 것에는 걷기, 달리기, 웅크리고 걷기, 수영하기, 날기, 뛰어 오르기, 떨어지기, 착륙하기, 그리고 빈둥거리기가 포함됩니다. 올바르게 애니메이트한다는 것에는 또한 동작에 바탕을 둔 것이 아닌 임의의 애니메이션 재생에 대한 기능성도 포함됩니다. 이 모든 애니메이션들이 넷 게임에서 적절하게 작용하게 됩니다. 이 문서에는 폰들이 올바르게 애니메이트하도록 하는 클래스 뿐만이 아니라, 애니메이션 코드를 여러가지 모델에 사용하는 방법을 보여주는 두 개의 하위 클래스 ExampleBoyExampleGirl 이 포함되어 있습니다. 이 남자와 여자는 다만 defaultproperties를 조절하는 경량의 클래스들입니다.

이 문서에는UnrealScript의 소스 코드 및 컴파일된 *.u 파일, 그리고 모든 것들을 작용하도록 하기 위한 애니메이션 및 텍스트 패키지가 포함되어 있습니다. 이 pawn의 예가 실행되는 것을 보기 위한 상세 내용에 대해서는 아래의 예제 설치하기 를 참고하십시오.

이 예제는 직선적인 코드 드롭, UDNBuild, UDNBuildOff, 그리고 런타임 또는 엔진의3323 빌드 (및 그 이후의 빌드)를 포함하여 어느2226 빌드에서도 사용할 수 있습니다.

클래스 설정

이 예제는 ExamplePawn.uc, ExampleGirl.uc, 그리고 ExampleBoy.uc, 3개의 클래스로 되어 있습니다. ExamplePawn 은 애니메이션과 동작을 위한 주요 기능성을 함유하고 있습니다. ExampleGirlExampleBoy 는 모두 ExamplePawn 을 연장하며, defaultproperties에서 그 자신의 모델, 애니메이션의 세트 및 충돌 실린더를 지정하는 것 외에는 아무것도 하지 않습니다.

새 모델

새 폰의 작성에서 가장 큰 부분을 차지하는 것은 아마 그 폰을 위한 새 모델을 만드는 일일 것입니다. 캐릭터 모델 작성법에 대한 더 자세한 정보는 모델링 목차? 문서를 참고하십시오.

일단 UKX 파일에 모델을 가지게 되면, defaultproperties 에서 다음과 같이 Mesh 변수를 지정함으로써 그 모델을 여러분의 폰에 사용할 수 있습니다:

Mesh=SkeletalMesh'UDN_CharacterModels_K.GenericMale'
- 또는 -
Mesh=SkeletalMesh'UDN_CharacterModels_K.GenericFemale'

어떤 경우에는 임포트한 모델이 크기가 맞지 않거나 방향이 올바르게 되어있지 않을 수 있습니다. 애니메이션 브라우저 참조?에 설명된 대로 Animation Browser에서 모델링의 스케일, 위치 및 방향을 바꿀 수 있습니다 .

클래스의 defaultproperties에서 모델에 대한 충돌 실린더의 CollisionRadiusCollisionHeight 도 조정해야 합니다.

PointOfView

폰이 컨트롤러에게 사로잡혔을 때 호출되는 simulated function bool PointOfView() 함수가 있습니다. 이 함수가 반환하는 값이 카메라가 세번째 인물일지(true) 첫번째 인물일지(false) 결정합니다. ExamplePawnbStartBehindView 변수를 추가하므로, 폰은 카메라가 시작하는 방법을 변경하기 위해 PointOfView 를 오버라이드할 필요 없이 다만 defaultproperties에서 이 변수를 설정하면 됩니다.

Pawn의 동작과 애니메이션

ExamplePawn 의 애니메이션은 대부분 물리 기반의 애니메이션을 사용하여 행해집니다. 물리 기반의 애니메이션이란 폰의 모션이 폰이 재생하는 애니메이션을 결정한다는 것을 의미합니다. 이것은 Unreal 엔진에서 일반적으로 애니메이션이 이루어지는 방법입니다. 이것은 단독 플레이어에서 작용할 뿐만 아니라, 복수 플레이어 상태에서도 아주 좋습니다. 각 클라이언트는 어떤 애니메이션이 재생되어야 할지 확인하기 위해 다만 주어진 폰의 모션을 보기만 하면 되기 때문입니다; 그밖의 다른 정보는 전달될 필요가 없습니다. 물리 기반 애니메이션을 유효화 하려면 defaultproperties에서 bPhysicsAnimUpdatetrue 로 설정합니다.

물리 기반 애니메이션에 대한 더 자세한 정보는 물리 기반의 애니메이션? 문서를 참고하십시오. 이 문서는 2226 코드 드롭을 근거로 하고 있지만 아직도 많은 도움이 됩니다.

3323 및 그 이후 버전에 대해서는 다음 섹션에서 사용자가 제어하는 애니메이션까지는 무시해도 됩니다. 물리 기반 애니메이션이 변경되었기 때문에 이는 완전히 관련성이 있는 것이 아닙니다. 이에 대한 자세한 사항은 물리 기반의 애니메이션? 문서를 읽어 보십시오. 버전 3323에서는 아래의 UnrealScript가 필요하지 않습니다. 다만 정확한 변수를 설정해야 합니다.

동작 애니메이션

물리 기반의 동작 애니메이션을 하려면 폰이 어떻게 움직이는지에 따라 6개의 애니메이션 이름을 사용해서 애니메이션을 재생합니다. 다음은 이 애니메이션 이름들입니다:

MovementAnims[0]      //앞으로
MovementAnims[1]      //뒤로
MovementAnims[2]      //왼쪽으로
MovementAnims[3]      //오른쪽으로
TurnLeftAnim
TurnRightAnim

폰이 앞으로 움직이면 MovementAnims[0] 에 의해 지정된 애니메이션이 루프됩니다. 폰이 왼쪽으로 움직이면 MovementAnims[2] 에 의해 지정된 애니메이션이 루프됩니다. 폰이 왼쪽으로 전진하면 전진과 좌향 애니메이션이 애니메이션 채널을 사용하여 한데 혼합된 다음 루프합니다. 폰이 가만히 서서 회전하면 TurnLeftAnim 이나 TurnRightAnim 이 루프됩니다. 폰이 빠르게 회전할수록 Turn 애니메이션이 빠르게 재생됩니다 .

6개의 애니메이션이 어떻게 걷기, 달리기, 웅크리기, 수영하기 등 모든 타입의 애니메이션들을 다 처리할 수 있는지 의아하게 여겨질 것입니다. 이에 대한 해답은 플레이어가 동작 타입을 바꿀 때마다 호출되는 함수 simulated function PlayMoving() 입니다. 이것은 플레이어가 달리기에서 걷기로, 또는 떨어지기에서 걷기로, 또는 날기에서 떨어지기로 동작을 바꾸었다는 것을 의미합니다. PlayMoving 은 폰이 현재 하고 있는 동작에 따라 MovenmentAnims 및 몇몇 경우 회전 애니메이션을 재설정하는 다른 함수들을 호출합니다. 예를 들면 PlayMoving 이 호출되고 =(Physics == PHYS_Flying)=이면, AnimateFlying() 이 호출됩니다. AnimateFlying() 은 다음과 같습니다:

//알맞은 비행 애니메이션 재생
simulated function AnimateFlying()
{
   MovementAnims[0]=FlyingAnims[0];
   MovementAnims[1]=FlyingAnims[1];
   MovementAnims[2]=FlyingAnims[2];
   MovementAnims[3]=FlyingAnims[3];
}

Flying은 turn 애니메이션을 사용하지 않으므로 재설정되지 않습니다. Crouching은 turn 애니메이션을 사용하며 AnimateCrouchWalking() 은 다음과 같습니다:

// 알맞은 웅크리기 애니메이션 재생
simulated function AnimateCrouchWalking()
{
   MovementAnims[0]=CrouchAnims[0];
   MovementAnims[1]=CrouchAnims[1];
   MovementAnims[2]=CrouchAnims[2];
   MovementAnims[3]=CrouchAnims[3];
   TurnLeftAnim=CrouchTurnAnims[0];
   TurnRightAnim=CrouchTurnAnims[1];
}

PlayeMovingAnimate...() 함수들은 아래에서 다룰 뛰어오르기, 착륙하기 그리고 떨어지기를 제외한 모든 동작 애니메이션을 처리합니다.

뛰어오르기, 착륙하기 및 떨어지기

뛰어오르기, 착륙하기 그리고 떨어지기는 PlayJump, PlayLandingAnimation, 그리고 PlayFalling 에 의해 다루어집니다. 이것들이 폰이 이런 행동들을 할 때 엔진이 호출하는 모든 함수들입니다. PlayJumpPlayFalling 은 아주 간단하며 아래와 같습니다:

simulated event PlayJump()
{
   AnimBlendToAlpha(LANDINGCHANNEL,0,0.0);
   if ( (Acceleration.X != 0) || (Acceleration.Y != 0) )
      PlayAnim(JumpMovingAnim, 1.0, 0.1);
   else
      PlayAnim(JumpStandingAnim, 1.0, 0.1);
}

simulated event PlayFalling()
{
   LoopAnim(FallingAnim, 1.0, 0.5);
}

PlayJump 에서는 처음에 AnimBlendToAlpha 가 호출됩니다. 아래에서 설명하는 착륙 채널이 빠르게 연속해서 여러 번 뛰어오르는 것을 방해하기 때문입니다.

착륙의 경우, 저는 애니메이션 채널을 지정할 필요가 있었습니다. 애니메이션을 기본 (채널 0)에서 재생하면 동작 애니메이션이 착륙 애니메이션을 겹쳐쓸 것이기 때문입니다. 모든 동작 애니메이션보다 높은 채널을 사용했기 때문에, 저는 착륙 애니메이션의 재생이 끝난 후 그 채널의 알파를 다시 0.0으로 블렌드해야 했습니다. 그러지 않으면 동작 애니메이션이 하나도 보이지 않게될 것입니다. 이 일은 AnimEnd 에서 이루어집니다. 아래의 함수들은 그 과정을 보여줍니다:

simulated event PlayLandingAnimation(float ImpactVel)
{
   AnimBlendParams(LANDINGCHANNEL, 1.0, 2.0, 2.0);
   PlayAnim(LandAnim, 0.4, 0.0, LANDINGCHANNEL);
}

simulated event AnimEnd(int Channel)
{
   Super.AnimEnd(Channel);

   ...
   if(Channel == LANDINGCHANNEL)
   {
      AnimBlendToAlpha(LANDINGCHANNEL,0,0.5);
   }
}

빈둥거리기

빈둥거리기는 아주 간단합니다. 폰이 그저 가만히 서있다는 것을 엔진이 알게되면 simulated function PlayWaiting() 이 호출됩니다. 이 함수는 폰의 상태를 바탕으로 알맞은 애니메이션을 가진 LoopAnim 을 호출합니다 (아래의 함수 참고). LoopAnim 이 호출되면 이것은 속도를 "1.0",그리고 트윈 시간을 "0.2" 로 설정합니다. 이는 애니메이션이 보통의 속도로 재생하고 기존의 애니메이션으로부터 0.2초 안에 트윈하도록 합니다. 지정된 채널이 없으므로 (LoopAnim 의 선택적 매개변수 중 하나), 애니메이션은 채널 0에서 재생되어 뼈대 전체에 영향을 줍니다. 동작 애니메이션들은 더 높은 채널에서 재생되므로, 캐릭터가 움직이기 시작하면 idle이 그 위에 블렌드 되어 보이지 않게 됩니다.

// 알맞은 idle 애니메이션 재생
simulated function PlayWaiting()
{
   if(Physics == PHYS_Falling)
      LoopAnim(FallingAnim, 1.0, 0.2);
   else if(Physics == PHYS_Flying)
      LoopAnim(FlyIdle, 1.0, 0.2);
   else if(Physics == PHYS_Swimming)
      LoopAnim(SwimIdle, 1.0, 0.2);
   else
   {
      if(bIsCrouched)
         LoopAnim(CrouchIdle, 1.0, 0.2);
      else
         LoopAnim(StandIdle, 1.0, 0.2);
   }
}

사용자가 제어하는 애니메이션

사용자가 제어하는 애니메이션이란 UT2004에서의 조롱하기처럼, 사용자가 버튼을 누르거나 명령을 집행하면 폰이 애니메이션을 재생하는 것을 말합니다. 단독 플레이어 상태에서는 이것이 매우 쉽습니다. 유감스럽게도 넷 게임에서는 이것이 훨씬 어려워집니다. 위에서 언급한 것처럼, 애니메이션은 네트워크를 통해 보내지지 않기 때문입니다.

이것이 함수 simulated event SetAnimAction(name NewAction) 와 변수 var name AnimAction 이 있는 이유입니다. 이것들은 서버에서 애니메이션 데이터를 모든 클라이언트에게 보내는 일을 함께 하도록 설계되어 있습니다. 서버에서 SetAnimAction 이 호출되면, 이는 서버에서 모든 클라이언트에게 복제된 AnimAction 을 변경합니다. 클라이언트가 새 AnimAction 을 수신하면, C++ 코드가 AnimAction 이 신규인지를 간파하고 그 클라이언트에서 새 애니메이션과 함께 SetAnimAction 을 호출합니다. 그 다음 새 애니메이션이 SetAnimAction 에 의해 재생됩니다. 애니메이션 재생이 끝나면 AnimAction 이 클라이언트와 서버 양측에 모두 설정되어, 다음번에 SetAnimAction 이 호출되면 모든 것들이 다시 작용하게 됩니다. 이를 위한 코드는 다음과 같습니다:

// idle 애니메이션 채널에서 모든 클라이언트가 한 애니메이션을 재생하도록 하기 위한 호출
simulated event SetAnimAction(name NewAction)
{
   AnimAction = NewAction;
   PlayAnim(NewAction); // idle 채널인 베이스 채널에서 재생
   bPlayedAnimAction = true;
}

simulated event AnimEnd(int Channel)
{
   Super.AnimEnd(Channel);

   if(Channel == 0 && bPlayedAnimAction) //idle 채널
   {
      PlayWaiting(); //보통의 idle로 재설정
      bPlayedAnimAction = false;
      AnimAction = '';
   }
   ...
}

Scripting Physics

폰을 제어하기 위해 스크립트된 시퀀스를 사용할 경우, ScriptedController 는 함수 SetMovementPhysics() 가 구현될 것을 기대합니다. SetMovementPhysicsPawn.uc 에서 정의되지만 본체를 가지고 있지 않습니다. 여러분 고유의 구현을 가지고 있지 않은 경우, 여러분이 스크립트 하고자하는 폰은 그 물리가 "PHYS_None"인 상태로 공중에 매달려 있게 됩니다. 아래의 SetMovementPhysics 구현은 간단하지만 훌륭하게 작용합니다.

// 스크립트된 시퀀스에 대해 정확하게Physics 설정
function SetMovementPhysics()
{
   if (Physics == PHYS_Falling)
      return;
   if ( PhysicsVolume.bWaterVolume )
      SetPhysics(PHYS_Swimming);
   else
      SetPhysics(PHYS_Walking);
}

예제 설치하기

Unreal 런타임

런타임을 사용하는 분들은ExamplePawns.zip을 다운로드하여 압축을 푼 다음, ExamplePawns.urm 을 실행하면 됩니다. ExamplePawns.urm 을 실행할 수 없다면, 이는 아마도 런타임을 설치하는 동안 "Runtime modification association" 박스의 체크를 취소했기 때문일 것입니다. 이 경우에는 아래의 단계들을 따라 해야 합니다:

  1. ExamplePawns.zip을 열어 ExamplePawns.urm 을 런타임의 "System" 디렉토리로 끌어냅니다.
  2. 런타임의 "System" 디렉토리에서 명령 프롬프트를 엽니다.
  3. "setup install ExamplePawns.urm " 을 입력합니다.

어떤 경우이든, 설치 윈도우에 제시된 지시대로 따라 하면 런타임에 대한 폰의 예가 설치될 것입니다.

폰들이 설치되면 이것들을 여러가지 방법으로 사용할 수 있습니다. User.ini 를 변경하여 폰의 타입을 지정할 수 있습니다. User.ini[DefaultPlayer] 섹션에서 다음과 같이 Class 를 설정하십시오:

Class=MyFirstExample.ExampleBoy
- 또는 -
Class=MyFirstExample.ExampleGirl

명령 프롬프트에서 다음 중 하나를 사용하여 게임을 실행할 수도 있습니다. 이 방법은 또한 User.ini 를 변경하게 됩니다.

UE2Runtime EM_Runtime?Class=MyFirstExample.ExampleBoy
- 또는 -
UE2Runtime EM_Runtime?Class=MyFirstExample.ExampleGirl

또 한 가지 방법은 게임에서 콘솔에 다음 중 한가지를 타이프하는 것입니다. 이 방법도 User.ini 를 변경하게 됩니다.

Open EM_Runtime?Class=MyFirstExample.ExampleBoy
- 또는 -
Open EM_Runtime?Class=MyFirstExample.ExampleGirl

코드 드롭, UDNBuild, UDNBuildOff

UDNBuild나 UDNBuildOff를 사용하는 경우에는 MyFirstPawn_UDNBuild.zip을 다운로드하여 여러분의 엔진 빌드에 압축을 해제하십시오.

2226 코드 드롭을 사용하는 경우에는 MyFirstPawn_CodeDrop.zip을 다운로드하여 여러분의 엔진 빌드에 압축을 해제하십시오. 3323 및 그 이후 버전에 대해서는 다운로드 MyFirstExample_CodeDrop3323.zip를 사용하십시오.

이제 User.ini 을 변경하여 폰의 타입을 지정함으로써 새 폰으로 플레이할 수 있습니다. User.ini[DefaultPlayer] 섹션에서 다음과 같이 Class 를 설정하십시오:

Class=MyFirstExample.ExampleBoy
- 또는 -
Class=MyFirstExample.ExampleGirl

다음 인수들로 명령줄에서 게임을 실행할 수도 있습니다. 이 방법도 User.ini 를 변경하게 됩니다.

UT2004 <YourMap>?Class=MyFirstExample.ExampleBoy
-또는 -
UT2004 <YourMap>?Class=MyFirstExample.ExampleGirl

또 한가지 방법은 위의 행을 게임 내 콘솔에 타이프하는 것입니다. 이 경우에는 "UT2004"를 "Open"으로 대체하십시오. 이 방법 또한 User.ini 를 변경하게 됩니다.

넷 플레이에서의 폰 사용

이 폰들을 넷 플레이에서 사용하고 싶다면 게임을 호스트하는 컴퓨터에서 몇 가지 일들을 처리해야 합니다.

먼저 <YourGame.ini> (예: UE2Runtime.ini 또는 UT2004.ini)을 편집하여 ServerPackages 목록에 "MyFirstExample" 를 포함시킵니다. ServerPackages 목록은 INI 파일의 [Engine.GameEngine] 섹션에 있는데, 이 섹션에 다음 행만 추가하면 됩니다:

ServerPackages=MyFirstExample

다음에는 MD5 데이터베이스를 재빌드해야 합니다. 여러분의 엔진 빌드에서 "System" 디렉토리를 열어 명령 프롬프트에 다음과 같이 입력하십시오:

UCC MASTERMD5 -c *.U

이제 여러분은 게임을 호스트할 수 있으며 다른 사람들이 여기에 접속하여 함께 달리고/날고/수영할 수 있습니다. 게임을 호스트하려면 system 디렉토리의 명령 프롬프트에서 다음과 같이 입력하면 됩니다:

UE2Runtime <YourMap> -server
- 또는 -
UW <YourMap> -server

예제 설치하기 섹션에서 설명한 대로 서버에 접속할 수 있는데, 맵 이름 대신 서버의 IP 주소를 사용하십시오. 명령줄에서 다음의 예와 같이 타이핑하면 됩니다:

UE2Runtime 192.168.1.112?Class=MyFirstExample.ExampleGirl

예제 변경하기 - UnrealEd에서의 예제 사용

주어진 코드를 변경하고 싶거나 UnrealEd에 ExamplePawns 를 배치하기 원할 경우에는, <your_game>.ini (예: UW.ini 또는 UE2Runtime.ini)의 EditPackages 목록에 "MyFirstExample" 를 추가해야 할 것입니다. INI 파일을 열어 텍스트 검색으로 "EditPackages"를 찾은 다음, 목록의 맨 뒤에 "EditPackages=MyFirstExample" 행을 추가하면 됩니다. 여기에는 목록이 2개 있으므로 이 행을 두 목록에 모두 추가하도록 확실히 하십시오. 코드를 변경할 경우에는 system 디렉토리에서 기존의 MyFirstExample.u 파일을 삭제한 다음, 명령줄에 "ucc make" 를 타이프하여 변경된 것을 재컴파일할 수 있습니다