GoW3 에서의 커버는 GoW2 것과 크게 다르지 않다. 기본적인 구조는 여기 를 보면 되고
대신 다음의 변경점이 생겼다.
커버에서는 slip, mantle, swatturn, 등의 다양한 액션을 취할 수 있다. 하지만 설치된 커버와 주변 환경과의 이해관계에 따라 이 중에서 수행하지 못하는 액션도 있을 것이다.
예를 들어 높은 장애물에서는 mantle 을 하지 못할 것이고 장애물의 가장자리가 아니라면 slip 이나 swatturn 의 행동을 할 수 없을 것이다.
GoW3 에서는 이런 액션의 가능 여부를 실시간으로 계산하는 것이 아니라 에디터에서 미리 계산하여 해당 커버에 플래그 형태로 저장해 둔다.1)
그리고 런타임에는 이 플래그를 조회하여 현재 커버에서 수행할 수 있는 액션들을 가려낸다.
에디터에서 커버를 빌드하는 방법은 크게 두가지가 있는데
두가지 경우 모두 ACoverLink::BuildSlotInfoInternal 함수로 들어오는데
void ACoverLink::BuildSlotInfoInternal( ... ) { ... if ( Slot.bCanMantle ) { Slot.bCanMantle = Scout->CanDoMove( TEXT("MANTLE"), this, SlotIdx, bSeedPylon ); // Scout 에게 mantle 액션 가능여부 판별토록 위임. } // 이하 다른 액션들도 마찬가지 ... }
위와 같이 Scout 에게 위임한다. 이어서 GearScout 를 보면
UBOOL AGearScout::CanDoMove( ... ) { ... ACoverLink* Link = Cast<ACoverLink>( Nav ); if ( ParseCommand( &Str, TEXT("MANTLE") ) ) { ... return CanMantle( SlotLocation, SlotRotation, 0, Link ); // mantle 여부 체크 } ... } UBOOL AGearScout::CanMantle( ... ) { ... // 블라블라 }
이런 식으로 되어 있다.
에디터에서 커버를 편집하는 방식과 그에 따른 코드 흐름에 대해 알아본다.
에디터에서 특정 대상을 편집하는 것에 대한 정의는 UnrealEd 프로젝트에 UnEdModes.h 와 UnEdModes.cpp 에 있다.
코드를 보면 알겠지만 Cover 이외 다양한 오브젝트들의 에디트 방식을 여기서 정의하고 있다.2)
enum EEditorMode { EM_None, EM_Default, EM_TerrainEdit, EM_Geometry, EM_StaticMesh, ... EM_CoverEdit, // 여기서 에디트모드 타입 추가 ... }; ... class FEdModeCoverEdit : public FEdMode { private: UBOOL bCanAltDrag; UBOOL bTabDown; ACoverLink* LastSelectedCoverLink; FCoverSlot* LastSelectedCoverSlot; public: FEdModeCoverEdit(); virtual ~FEdModeCoverEdit(); virtual void Enter(); // 선택 되었을 경우 발생하는 이벤트. virtual void Exit(); // (선택된 상태에서) 포커스가 해제된 경우 발생하는 이벤트 virtual UBOOL InputKey( ... ); // 키(마우스포함) 를 눌렀을 경우 발생하는 이벤트 virtual UBOOL InputDelta( ... ); // 오브젝트를 이동/회전/확대 할 경우 발생하는 이벤트 virtual void ActorSelectionChangeNotify(); // 선택 되었을 경우 발생하는 이벤트. 마지막으로 선택된 CoverLink 를 캐싱해둔다. virtual UBOOL UsesTransformWidget(); virtual UBOOL UsesTransformWidget( ... ); // Space 로 에디트모드를 변경할 경우 (이동/회전/확대) 발생하는 이벤트 virtual FVector GetWidgetLocation(); // 현재 오브젝트의 위치를 리턴. virtual UBOOL HandleDragDuplicate(); // Alt 드래그로 오브젝트를 복제할 경우 발생하는 이벤트 virtual UBOOL HandleDuplicate(); // 오브젝트 복제가 일어날 때 발생하는 이벤트. UUnrealEdEngine::Exec_Actor 에서 "DUPLICATE" 신호 virtual UBOOL HandleClick( ... ); // 화면에 마우스 클릭 시 발생하는 이벤트 virtual void DrawHUD( ... ); // UI 표시 };
GetWidgetLocation 함수는 화면에 위젯을 그리기 위해 현재 선택한 오브젝트의 위치를 얻기 위한 용도로 사용된다.
void FWidget::Render( ... ) { ... // 위치를 얻어서 FVector Loc = GEditorModeTools().GetWidgetLocation(); // 현재 에디트 모드에 따라 적당한 위젯을 그린다. switch ( GEditorModeTools().GetWidgetMode() ) { case WM_Translate: Render_Translate( View, PDI, Loc, bDrawWidget ); break; case WM_Rotate: Render_Rotate( View, PDI, Loc, bDrawWidget ); break; case WM_Scale: Render_Scale( View, PDI, Loc, bDrawWidget ); break; ... } ... }