UDN
Search public documentation:
UnrealScriptVariablesKR
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
언리얼스크립트 변수
문서 변경내역: Tim Sweeney 원저. 홍성진 번역.
개요
변수 영역
- 인스턴스 변수 - 전체 오브젝트(클래스나 구조체)에 적용되며, 속하는 오브젝트의 수명 동안 사용할 수 있습니다. 인스턴스 변수는 오브젝트의 생성과 소멸에 맞춰 생성되고 소멸됩니다. 오브젝트에 속하는 스태틱 이외 함수 안에서 사용할 수 있으며, 다른 오브젝트에서 변수가 속하는 오브젝트로의 리퍼런스를 통해서도 접근할 수 있습니다.
- 로컬 변수 - 함수에 대해 "로컬", 다른 말로 특정 함수에 속하는 변수입니다. 함수가 실행되는 동안에만 활성화됩니다. 로컬 변수는 함수 실행 시작시 생성되며, 함수 실행 종료시 소멸됩니다. 다른 함수에서 사용할 수 없고, 다른 오브젝트에서 접근할 수도 없습니다.
변수 선언
var
또는 local
키워드 중 하나, 이어서 선언할 변수 종류에 따른 옵션 지정자 중 하나, 마지막으로 변수에 지어줄 이름으로 구성됩니다.
var Type Name; ... local Type Name;
var
키워드로 선언하고, 로컬 변수는 local
키워드로 선언합니다.
UnrealScript 에서 인스턴스 변수 선언 예제는 다음과 같습니다:
class MyClass extends Actor; // 인스턴스 변수는 다른 함수나 스테이트가 // 선언되기 전에 선언해야 합니다. var int A; // 인티저 변수 "A" 를 선언합니다. var byte Table[64]; // 64 바이트 스태틱 변수 "Table" 을 선언합니다. var string PlayerName; // 스트링 변수 "PlayerName" 을 선언합니다. var actor Other; // 액터 인스턴스로의 리퍼런스를 할당받을 수 있는 변수를 선언합니다. var() float MaxTargetDist; // "MaxTargetDist" 라는 이름의 플로트 변수를 선언하고, 그 값을 언리얼 에디터 프로퍼티 창에서 수정할 수 있도록 합니다. struct RangeVector { var Vector Min; // 구조체 안에 "Min" 라는 이름의 벡터 변수를 선언합니다. var Vector Max; // 구조체 안에 "Max" 라는 이름의 벡터 변수를 선언합니다. }; var RangeVector Bounds; // "Bounds" 라는 이름의 범위벡터 변수를 선언합니다. function foo { ... } var int B; // 에러가 납니다.
function int Foo() { // 로컬 변수는 함수 본문 내 // 다른 코드보다 앞서 선언해야 합니다. local int Count; local float Seconds; Count = 1; // 여기서 로컬 변수를 선언하면 에러가 납니다. local float Minutes; return Count; }
변수 지정자(Specifier)
변수는const
처럼 변수의 속성을 더욱 자세히 설명하는 지정자를 추가할 수 있습니다. 실제로 범용 프로그래밍 언어에서는 보기 힘든 지정자가 꽤 많이 있는데, 그 이유는 주로 UnrealScript 가 게임 이나 환경 전용 개념을 선천적으로 지원하도록 하기 위해서입니다:
- config 환경설정
- 이 변수는 환경설정 가능해 집니다. 현재 값은 .ini 파일에 저장할 수 있으며, 생성시 로드됩니다. default properties 에 값을 줄 수 없습니다. const 임을 내포합니다.
- globalconfig 전역 환경설정
- 서브클래스에서 덮어쓸 수 없다는 점만 빼면 config 과 같습니다. default properties 에 값을 줄 수 없습니다. const 임을 내포합니다.
- localized 현지화
- 이 변수의 값은 정의된 현지화 값을 갖습니다. 대부분 문자열에 사용됩니다. const 임을 내포합니다. 자세한 것은 Localization Reference KR, Strings In UnrealScript KR 페이지를 참고하시기 바랍니다.
- const 상수화
- 변수의 내용을 상수로 간주합니다. UnrealScript 에서는 const 변수의 값을 읽을 수는 있지만 쓸 수는 없습니다. "Const" 는 (MoveActor 함수 호출을 통해서만 설정할 수 있는) 액터의 Location 처럼, UnrealScript 를 통해서는 안전하게 업데이트할 수 없고 엔진에서 업데이트를 시켜야 하는 변수에만 사용됩니다.
- private 개인
- 프라이빗 변수는 클래스의 스크립트를 통해서만 접근할 수 있고, (서브클래스를 포함한) 어떤 클래스에서도 접근할 수 없습니다.
- protected 보호
- 프로텍티드 변수는 클래스와 그 서브클래스에서만 접근할 수 있고, 다른 클래스에서는 접근할 수 없습니다.
- privatewrite 개인 쓰기
- 프라이빗 롸이트 변수는 선언된 클래스 밖에서는 const 입니다.
- protectedwrite 보호 쓰기
- 프로텍티드 롸이트 변수는 선언된 클래와 그 서브클래스 밖에서는 const 입니다.
- repnotify 리플 통지
- 리플리케이션을 통해 이 프로퍼티에 대한 이 값을 받았을 때, 이 액터는 (ReplicatedEvent 함수를 통해) 노티파이(통지)를 받아야 합니다.
- deprecated 폐기
- 이 변수는 곧 제거될 예정이라 에디터에서 접근할 수 없게 될 것임을 나타냅니다. 이 프로퍼티는 로드는 되지만 저장되지는 않습니다.
- instanced 인스턴스
- 오브젝트 프로퍼티 전용. 이 클래스의 인스턴스가 생성되면, 디폴트로 이 변수에 할당되는 오브젝트 고유 사본이 주어집니다. 클래스 default properties 에 정의된 서브오브젝트 인스턴싱에 사용됩니다.
- databinding 데이터 바인딩
- 이 프로퍼티는 데이터 스토어 시스템으로 조작할 수 있습니다.
- editoronly 에디터 전용
- 이 프로퍼티의 값은 언리얼 에디터나 커맨드렛 실행시에만 로드됩니다. 게임 도중엔 이 프로퍼티에 대한 값은 버립니다.
- notforconsole 콘솔용 아님
- 이 프로퍼티 값은 PC 에서 실행할 때만 로드됩니다. 콘솔에서는 이 프로퍼티에 대한 값은 버립니다.
- editconst 에디터 const
- 에디터. 언리얼 에디터에서 볼 수는 있으나 수정은 안되는 변수입니다. editconst 변수는 "const" 임을 암시하지는 않습니다.
- editfixedsize 에디터 고정 크기
- 에디터. 동적 배열에만 유용합니다. 사용자가 언리얼 에디터 프로퍼티 창을 통해 배열 길이를 바꾸지 못하도록 합니다.
- editinline 에디터 즉시
- 에디터. 이 변수가 리퍼런스하는 오브젝트의 프로퍼티를 언리얼 에디터의 프로퍼티 인스펙터에서 사용자가 바로 수정할 수 있도록 합니다. (오브젝트 리퍼런스 배열을 포함해서 오브젝트 리퍼런스에만 유용합니다.)
- editinlineuse 에디터 즉시 사용
- 에디터. editinline 에 관계된 동작에 추가로, 에디터에 이 오브젝트 리퍼런스 옆에 "사용" 버튼을 추가합니다.
- noclear 비우기 없음
- 에디터. 이 오브젝트가 에디터에서 None 으로 설정되지 않도록 합니다.
- interp 보간
- 에디터. 이 값은 마티네의 Float 또는 Vector Property Track 으로 시간에 따라 굴릴 수 있음을 나타냅니다.
- input 입력
- 고급. 변수를 언리얼의 입력 시스템에 접근 가능하도록 만들어, (버튼 눌림이나 조이스틱 이동같은) 입력을 직접 매핑시킬 수 있도록 합니다. "byte" 와 "float" 변수형에만 관련있습니다.
- transient 휘발성
- 고급. 일시적으로 사용할 변수로, 오브젝트의 지속적 상태의 일부가 아님을 선언합니다. 휘발성 변수는 디스크에 저장되지 않습니다. 휘발성 변수는 오브젝트 로드시 해당 변수에 대한 클래스의 디폴트 값으로 초기화됩니다.
- duplicatetransient 휘발성 복제
- 고급. 이 변수의 값은 (StaticDuplicateObject 등을 통해) 오브젝트의 이항 복제를 만들 때, 변수의 값을 클래스의 디폴트 값으로 리셋시켜야 함을 나타냅니다.
- noimport 임포트 없음
- 고급. 이 변수는 T3D 텍스트 임포트시 건너뛰어야 함을 나타냅니다. 다른 발로 이 변수의 값은 오브젝트를 임포트하거나 복사/붙여넣기할 때, 새로 생기는 오브젝트로 전송되지 않는다는 뜻입니다.
- native 토종
- 고급. 이 변수는 언리얼스크립트가 아닌, 네이티브 C++ 코드에 의해 로드되고 저장됨을 선언합니다.
- export 익스포트
- 고급. 오브젝트 프로퍼티 (또는 오브젝트 배열)에만 유용합니다. 이 프로퍼티에 할당된 오브젝트는 (복사/붙여넣기로) 복사될 때나 T3D 로 익스포트될 때, 오브젝트 리퍼런스만 출력하고 마는 것이 아닌, 그 전체를 하위오브젝트 블록으로 익스포트해야 함을 나타냅니다.
- noexport 익스포트 없음
- 고급. 네이티브 클래스에만 유용합니다. 이 변수는 자동 생성 클래스 정의에 포함되지 않습니다.
- nontransactional 트랜잭션(히스토리) 아님
- 고급. 이 변수 값에 대한 변경은 에디터의 되돌리기/다시하기 히스토리에 포함되지 않습니다.
- pointer{type} 포인터
- 고급. 이 변수는 type (옵션)으로의 포인터입니다. 문법에 주의: pointer varname{type}.
- init 초기화
- 고급. 이 프로퍼티는 FStringNoInit 나 TArrayNoInit 가 아닌, FString 나 TArray 로써 헤더 파일로 익스포트됩니다. 네이티브 클래스에서 선언된 문자열이나 동적 배열에만 적용 가능합니다. 'Init' 프로퍼티는 디폴트 값으로 주면 안되는데, 디폴트 값은 오브젝트 생성시 비워지기 때문입니다. (자세한 것은 Strings In UnrealScript KR, Strings In Native Code KR 참고.)
- repretry 리플리케이션 재시도
- 고급. 구조체 프로퍼티 전용입니다. (오브젝트 리퍼런스를 네트워크 상에서 아직 serialize 할 수 없었다든가 해서) 이 프로퍼티 전체 전송에 실패한 경우 리플리케이션을 재시도합니다. 단순 리퍼런스에 대해서는 디폴트로 켜져 있으나, 구조체의 경우는 대역폭 비용때문에 바람직하지 않은 경우가 많아, 이 옵션으로 지정하지 않으면 디폴트로는 꺼져 있습니다.
- allowabstract 추상화 허용
- 고급. 클래스 리퍼런스 전용. 에디터 안에서 이 변수에 추상 클래스를 할당할 수 있도록 합니다.
- out 아웃
- 함수 파라미터용으로만 사용할 수 있는 지정자입니다. 자세한 것은 함수 파라미터 지정자 부분을 참고하시기 바랍니다.
- coerce 강압
- 함수 파라미터용으로만 사용활 수 있는 지정자입니다. 자세한 것은 함수 파라미터 지정자 부분을 참고하시기 바랍니다.
- optional 옵션
- 함수 파라미터용으로만 사용할 수 있는 지정자입니다. 자세한 것은 함수 파라미터 지정자 부분을 참고하시기 바랍니다.
- skip 생략
- 함수 파라미터용으로만 사용할 수 있는 지정자입니다. && 나 || 같은 이진 논리 연산자에만 사용됩니다. 첫 항을 통해 논리 연산 결과를 확정할 수 있으면 둘째 항 연산은 생략할 수 있도록, 컴파일러에 약간의 코드를 찔러넣습니다.
다음과 같은 식에서 C 와 같은 스타일로 동작하도록 합니다:if( ++a==10 && ++b==10 )
메타데이터
변수는 엔진이나 에디터가 사용하는 변수 단위별 메타데이터 형태로 추가 정보를 주어 함수성을 확장시킬 수도 있습니다. 메타데이터는 여러가지로 활용될 수 있지만, 그 중에서도 표시명, 툴팁, 최소-최대값을 지정하는 데 사용할 수 있습니다. 메타데이터를 변수에 연결하려면, 변수명 뒤에 변수 선언을 추가하고 세미콜론으로 선언을 마무리합니다. 각괄호 < > 안에 파이프 글자 (|
) 로 구분된 태그=값
쌍 시리즈로 메타데이터를 지정합니다.
예를 들어:
var float MyVar<DisplayName=My Float Variable|Tooltip=This is a float variable with additional metadata specified|UIMin=0.0|UIMax=10.0|ClampMin=0.0|ClampMax=5.0>;
디폴트 프로퍼티
UnrealScript 에서 변수의 디폴트 값은, 일부 프로그래밍 언어에서 가능하듯 변수 선언시에 지정되지 않습니다. 추가로 UnrealScript 에서 클래스를 생성할 때는, 디폴트 값을 준비하기 위한 "생성자"(constructor) 함수같은 개념이 없습니다. 대신 UnrealScript 는 클래스를 정의하는 스크립트 말미에 추가되는defaultproperties
블록을 사용하여, 해당 클래스 내 선언되는 인스턴스 변수에 대한 디폴트 값을 정의합니다. 이 블록에서는 코드를 실행할 수 없으며, UnrealScript 내 다른 곳에서 사용되는 문법과는 약간 다른 규칙을 따릅니다.
예:
defaultproperties { IntVar=3 FloatVar=2.5 StringVar="This is a string" ArrayVar(0)=2 ArrayVar(1)=4 ArrayVar(2)=7 ArrayVar(3)=1 }
변수형
기본 데이터형
다른 언어에도 흔히 쓰이고 UnrealScript 에서도 지원되는 기본적인 변수형은 다음과 같습니다:- byte
- 1 바이트 값으로, 범위는
0
~255
입니다. - int
- 32 비트 정수 값입니다.
- bool
- 불리언 값으로,
true
(참) 또는false
(거짓) 입니다. - float
- 32 비트 부동 소수점 값입니다.
- string
- 문자열입니다. (Strings In UnrealScript KR 참고.)
- constant
- 수정할 수 없는 변수입니다.
- enumeration
- 여러가지 미리정의된 이름의 정수 값 중 하나를 고를 수 있는 변수입니다. 예를 들어 Actor 스크립트에 정의된 ELightType 열거형은 다이내믹 라이트에 대해 설명하며,
LT_None
,LT_Pulse
,LT_Strobe
등과 같은 값 중 하나를 선택합니다.
통합 데이터형
- array<Type> 배열
-
Type
변수 길이의 배열입니다. - struct 구조체
- C 구조체와 마찬가지로 UnrealScript 구조체를 통해 하위 변수를 포함하는 변수형을 새로 만들 수 있습니다. 두 가지 자주 사용되는 언리얼 구조체가 있는데, X, Y, Z 성분으로 구성된
vector
(벡터)와, pitch(피치, 상하), yaw(요, 좌우), roll(롤, 횡전) 성분으로 구성된rotator
(로테이터) 입니다. (자세한 것은 구조체 부분 참고.)
언리얼 타입
- Name 이름
- 언리얼 내 (함수, 스테이트, 클래스 등의 이름같은) 항목의 이름입니다. 이름은 전역 이름 테이블 속에 인덱스로 저장됩니다. 이름은 64 글자까지의 단순한 문자열에 해당합니다. 이름은 한 번 생성되면 변경할 수 없다는 점에서 string 과는 다릅니다. (자세한 정보는 Strings In UnrealScript KR 참고.)
- Object and Actor references 오브젝트와 액터 리퍼런스
- 월드의 다른 오브젝트나 액터를 가리키는 변수입니다. 예를 들어 Pawn 클래스는
Enemy
액터 리퍼런스를 갖고 있어, 폰이 어느 액터를 공격할지 나타냅니다. 오브젝트와 액터 리퍼런스는 매우 강력한 도구로, 다른 액터의 변수와 함수를 접근할 수 있도록 해 주기 때문입니다. 예를 들어 Pawn 스크립트에서, 적의TakeDamage
함수를 호출하기 위해Enemy.TakeDamage(123)
같은 식으로 작성하여 적에게 대미지를 입혔다 칩시다. 오브젝트 리퍼런스는None
이라는, C 에서NULL
포인터에 상응하는 특수한 값을 가질 수도 있습니다. "이 변수는 아무 오브젝트도 가리키고 있지 않습니다." 라는 것입니다. - Delegate 델리게이트
- UnrealScript 함수에 대한 리퍼런스를 담습니다.
편집성
var() int MyInteger; // 디폴트 카테고리에 편집가능 정수 선언 var(MyCategory) bool MyBool; // "MyCategory" 에 편집가능 정수 선언
editconst
로 선언할 수도 있는데, 언리얼 에디터에서 볼 수는 있어도 편집할 수는 없는 것을 말합니다. 주의할 것은 에디터에서 수정할 수 없다 뿐이지, 스크립트에서도 수정할 수 없는 것은 아닙니다. 제대로 const
(수정불가)이면서도 에디터에서 변수가 보이게는 하려면, const editconst
로 선언해야 합니다:
// MyBool 은 에디터에 보이지만 편집할 수는 없습니다. var(MyCategory) editconst bool MyBool; // MyBool 은 에디터에 보이지만 편집은 안되며, // 스크립트에서도 바꿀 수 없습니다. var(MyCategory) const editconst bool MyBool; // MyBool 은 에디터에 보이며 설정도 가능하지만, // 스크립트에서는 바꿀 수 없습니다. var(MyCategory) const bool MyBool;
배열
var int MyArray[20]; // int 20 개 배열을 선언합니다.
동적 배열
전에는 정적인 배열을 다뤘습니다. 크기(, 즉 배열에 있는 요소(element)의 갯수)가 컴파일 시간에 정해져 변경될 수 없다는 뜻입니다. 동적 배열과 정적 배열은 일단 다음과 같은 특징을 공유합니다:- 고정된 탐색 시간 - 배열에 있는 요소의 갯수가 얼마나 되든, 코드가 배열의 어느 요소에 접근하는 데 걸리는 시간은 항상 같습니다.
- 요소 유형 무제한 - 정수든, 벡터든, 액터든, (동적 배열만 가능한 불리언을 예외로 하고) 어떤 종류의 배열도 만들 수 있습니다.
- 접근 방식 - 배열의 인덱스를 가진 어느 요소에도 접근할 수 있으며, 역으로 배열 범위 밖의 인덱스에 있는 요소에 접근하려 하면 아무것도 접근하지 않았다는 throw 를 냅니다.
>>
연산자로 해석해 버립니다. 예를 들어:IntList 라는 이름의 정수 동적 배열 선언:
var array<int> IntList;
class<PlayerController>
유형 동적 배열 선언:
var array<class<PlayerController> > Players;
IntList.MethodName()
입니다. 사용할 수 있는 동적 배열 메서드는 다음과 같습니다:
- Add(int Count): 배열의 길이를 Count 만큼 연장합니다. FArray::AddZeroed() 와 같습니다.
- Insert(int Index, int Count): Index 는 요소를 삽입하려는 배열 인덱스이고, Count 는 삽입할 요소 수입니다. 배열 해당 위치의 기존 요소는 뒤로 밀고, 새로운 요소를 만들어 지정된 위치에 삽입합니다. 인덱스 3 에 요소를 5 개 삽입하면, 인덱스 3 부터 시작하는 배열 요소 전부는 (인덱스 값이) 5 만큼 올라갑니다. 인덱스 3 에 있던 기존 요소는 인덱스 8 이 되고, 요소 4 는 9 가 되고, 등등입니다. 새로이 추가되는 요소는 디폴트 값(structdefaultproperties 를 포함하는 구조체를 제외한 모든 유형에는 0/null)으로 초기화됩니다.
- Remove(int Index, int Count): Index 는 요소를 제거하기 시작할 배열 인덱스이며, Count 는 제거할 요소의 수입니다. 배열에서 유효 인덱스 위치부터 시작해 요소 그룹을 제거할 수 있습니다. 제거할 범위보다 높은 인덱스는 인덱스 값이 변경되니, 동적 배열에 인덱스 값을 저장할 때는 이 점 주의하시기 바랍니다.
- AddItem(Item): 배열 끝에 Item 을 추가, 배열 길이를 하나 늘입니다.
- RemoveItem(Item): 선형 검색을 사용하여 Item 인스턴스가 있으면 제거합니다.
- InsertItem(int Index, Item): 배열 Index 위치에 Item 을 삽입, 배열 길이를 하나 늘입니다.
- Find(...) - 배열의 요소 인덱스를 찾습니다. Find 는 두 종류가 있습니다: 완전히 일치하는 요소값을 찾는 표준 방식과, 구조체의 단일 속성값에 따라 일치하는 구조체를 찾는 특수 방식이 있습니다.
- Find(Value): Value 는 검색할 값입니다. 배열에서 지정된 값에 일치하는 첫 번째 요소에 대한 인덱스, 혹은 배열에서 그 값을 찾지 못한 경우 -1 을 반환합니다. Value 에는 유효 표현식도 가능합니다.
- Find(PropertyName, Value): PropertyName 은 검색 대상 구조체 안의 (반드시 'Name' 유형인) 속성 이름, Value 는 검색할 값입니다. 배열에서 지정된 PropertyName 속성값에 일치하는 첫 번째 구조체에 대한 인덱스, 혹은 그 값을 찾지 못한 경우 -1 을 반환합니다. Value 는 유효 표현식도 가능합니다.
- Sort(SortDelegate) - SortDelegate 를 사용하여 배열 내용을 제자리 소팅합니다. SortDelegate 는 다음에 일치하는 시그너처를 가져야 합니다:
- delegate int ExampleSort(ArrayType A, ArrayType B) { return A < B ? -1 : 0; } // 반환값이 음수면 항목을 맞바꿔야 함을 나타냅니다.
Length 변수
동적 배열에는Length
라는 변수도 있는데, 동적 배열의 현재 길이(요소의 수)입니다. 위의 예에서 Length 에 접근하려면: IntList.Length
입니다. Length 변수는 읽기 뿐 아니라 직접 설정할 수도 있기에, 이를 통해 배열의 요소 수를 수정할 수도 있습니다. Length 변수를 직접 수정할 때, 배열 길이의 변화는 배열 '끝' 부분에 발생합니다. 예를 들어 IntList.Length = 5 라고 설정한 뒤 IntList.Length = 10 이라 설정하면, 방금 추가한 5 개의 요소는 배열 끝에 추가되며, 원래 5 개 요소의 순서와 값은 유지됩니다. Length 를 줄여도 마찬가지로 끝에서부터 빠집니다. 참고로 Insert() 로든 Length 를 늘려서든, 배열에 요소를 추가하면 그 값은 변수형의 디폴트 값(int 는 0, 클래스 리퍼런스는 None 등)으로 초기화됩니다. 요소 인덱스를 배열의 현재 Length 값보다 크게 설정해도 동적 배열의 길이를 늘일 수 있다는 점 알아두시면 좋습니다. Length 를 더 큰 값으로 설정한 것처럼 배열이 확장됩니다.
OldLength = Array.length
Array.Length = OldLength + 1
Array[OldLength] = NewValue
Array[Array.Length] = NewValue
Array.AddItem(NewValue)
Array[Array.length].myStructVariable = newVal
array<bool>
은 지원되지 않는 유형입니다!
미주 - 동적 배열은 리플리케이트되지 않습니다. 리플리케이트 가능하면서 인수가 둘(동적 배열로의 인덱스와 거기에 저장할 변수)인 함수를 대안으로 삼을 수는 있습니다만, 한 틱 동안 클라이언트와 서버의 요소 수가 달라진다는 점은 염두에 두어야 합니다.
동적 배열 반복처리
이제 동적 배열에foreach
명령이 지원되어 단순한 반복처리(iteration)가 가능합니다. 기본 문법은:
foreach ArrayVariable(out ArrayItem, optional out ItemIndex) { ... }
ArrayItem
은 배열 내 요소과 같은 유형이어야 합니다. 매번 반복시마다 인덱스를 증가시키고 항목은 물론 프로퍼티가 제공되면 인덱스도 출력합니다.
function IterateThroughArray(arraySomeArray) { local string ArrayItem; local int Index; foreach SomeArray(ArrayItem) { `log("Array iterator test #1:"@ArrayItem); } foreach SomeArray(ArrayItem,Index) { `log("Array iterator test #2:"@ArrayItem@Index); } }
구조체 (Struct)
구조체 정의
구조체 변수를 선언하기 전, 반드시 사용할 구조체를 정의해야 합니다. 정의는struct
키워드에다 구조체에 지을 이름을 붙인 다음, 대괄호 { } 안에 구조체를 이루는 변수들을 인스턴스 변수를 선언할 때와 마찬가지 문법을 사용해서 선언하면 됩니다. 대괄호를 닫은 다음에는 세미콜론이 와야 합니다.
벡터에 대한 구조체 정의 예는 다음과 같습니다:
// 3D 공간에서의 점 또는 방향 벡터.
struct Vector
{
var float X;
var float Y;
var float Z;
};
structdefaultproperties
블록을 추가하면 됩니다. 예를 들어 방금 정의한 Vector
구조체의 각 변수 디폴트 값을 1.0
으로 하고 싶다면, 이런 식으로 구조체를 정의하면 됩니다:
// 3D 공간에서의 점 또는 방향 벡터.
struct Vector
{
var float X;
var float Y;
var float Z;
structdefaultproperties
{
X=1.0
Y=1.0
Z=1.0
}
};
구조체 지정자
구조체에는 그 모든 인스턴스에 영향을 끼치는 지정자가 약간 있을 수도 있습니다. 지정자는 정의 내 구조체 이름과struct
키워드 사이에 놓입니다.
- atomic 원자성
- 이 구조체는 항상 단일 유닛으로 직렬화(serialize)되어야 함을 나타냅니다. 구조체의 프로퍼티가 지폴트와 다른 것이 있다면, 구조체의 모든 요소는 직렬화됩니다.
- atomicwhencooked 쿠킹시 원자성
- 쿠킹된 패키지 데이터 작업을 할 때만 'atomic' 옵션을 적용합니다.
- immutable 변경불가
- 이 구조체는 (디스크 공간이 절약되고 직렬화 성능이 향상되는) 이진 직렬화를 사용함을 나타냅니다. 패키지 버전을 증가시키지 않고 이 구조체에 멤버를 추가/제거하는 것은 안전하지 않습니다.
- immutablewhencooked 쿠킹시 변경불가
- 쿠킹된 패키지 데이터 작업을 할 때만 'immutable' 옵션을 적용합니다.
- strictconfig 엄격 환경설정
- 구조체 프로퍼티에 'config/globalconfig' 이 있을 때, 이 구조체에서 config/globalconfig 마킹된 프로퍼티만 .ini 파일에서 읽을 수 있음을 나타냅니다. (이 옵션이 없으면 구조체의 모든 프로퍼티가 설정 가능해 집니다)
구조체 변수 선언하기
구조체를 선언하면 해당 구조체 유형의 특정 변수를 선언할 준비가 된 것입니다:
// Vector 형 변수를 잔뜩 선언합니다.
var Vector Position;
var Vector Destination;
구조체 변수 사용하기
구조체 성분(component)에 접근하려면, 다음과 같은 코드를 사용합니다.function MyFunction() { Local Vector A, B, C; // 약간의 벡터 추가. C = A + B; // 벡터의 X 성분만 더합니다. C.X = A.X + B.X; // 벡터 C 를 함수에 전달합니다. SomeFunction( C ); // 특정 벡터 성분을 함수에 전달합니다. OtherFunction( A.X, C.Z ); }
- Vector 벡터
- 공간의 고유한 3D 점 또는 벡터로, X, Y, Z 성분이 있습니다.
- Plane 평면
- 3D 공간의 고유한 평면을 정의합니다. 한 평면은 (정규화된 것으로 간주된) X, Y, Z 성분에다, (평면에서 원점까지 최단 직선인) 평면의 노멀을 따라 원점에서 평면까지의 거리를 나타내는 W 성분을 더해 정의합니다.
- Rotator 로테이터
- 고유한 직교 좌표계를 정의하는 로테이션입니다. 로테이터에는 Pitch(상하), Yaw(좌우), Roll(횡전) 컴포넌트로 구성됩니다.
- Coords 좌표
- 3D 공간 내 임의의 좌표계입니다.
- Color 색
- RGB 색 값입니다.
- Region 구역
- 레벨 내 고유 컨벡스(볼록) 구역을 정의합니다.
열거형 (Enumerations)
EPhysics
열거형이 포함되어 있습니다. 이 변수는 PHYS_None
, PHYS_Walking
, PHYS_Falling
등 미리 지정된 값 중 하나로 설정 가능합니다.
내부적으로 열거형은 byte 변수로 저장됩니다. UnrealScript 를 디자인할 땐 열거형이 그리 필요하지는 않아 보였지만, 액터의 물리 모드가 (예를 들어) 3
으로 나오는 것 보다는 Phys_Swimming
으로 나오는 편이 코드 읽기가 더욱 쉬워집니다.
열거형을 선언하는 샘플 코드는 이렇습니다.
// EColor 열거형을, 세 가지 값으로 선언합니다. enum EColor { CO_Red, CO_Green, CO_Blue }; // 이제 EColor 형 변수를 둘 선언합니다. var EColor ShirtColor, HatColor; // 다른 방법으로는 이런 식으로 // 변수와 열거형을 같이 선언할 수 있습니다: var enum EFruit { FRUIT_Apple, FRUIT_Orange, FRUIT_Bannana } FirstFruit, SecondFruit;
LT_Steady
, PHYS_Falling
같은 식으로 선언합니다. 그냥 프로그래밍 스타일때문이지, 언어적인 필요에 의해서는 아닙니다.
UnrealScript 는 열거형이 정의된 클래스와 그 서브클래스에서만 (FRUIT_Apple
처럼) 무수식(unqualified) 열거형 태그를 인식합니다. 클래스 계층구조 내 다른 곳에 정의된 열거형 태그를 가리키려면, 먼저 "수식해 줘야" 합니다:
FRUIT_Apple // 언리얼에서 이 열거형 태그를 찾지 못하면... EFruit.FRUIT_Apple // 이렇게 수식해 줍니다.
var int MyIntArray[EFruit];
상수
- Integer 와 byte 상수는 단순한 수치로 지정합니다:
123
. integer 나 byte 상수를 16진수로 지정해야 한다면 이렇습니다:0x123
- Floating point 상수는 10진수 소수점으로 지정합니다:
456.789
- String 상수는 큰 따옴표로 묶어야 합니다:
"MyString"
- Name 상수는 작은 따옴표로 묶어야 합니다:
'MyName'
- Vector 상수는 X, Y, Z 값을 포함해야 합니다:
vect(1.0,2.0,4.0)
- Rotator 상수는 Pitch, Yaw, Roll 값을 포함해야 합니다:
Rot(0x8000,0x4000,0)
-
None
상수는 "no object" (또는 "no actor") 를 가리킵니다. -
Self
상수는 "this object" (또는 "this actor"), 즉 실행중인 스크립트를 소유하고 있는 오브젝트를 가리킵니다. - 일반적은 Object 상수는 오브젝트 종류에 오브젝트 이름을 작은 따옴표로 묶어 지정합니다:
texture'Default'
-
EnumCount
는 열거형으로 요소의 수를 나타냅니다:ELightType.EnumCount
-
ArrayCount
는 정적 배열 내 요소의 수를 나타냅니다:ArrayCount(Touching)
const LargeNumber=123456; const PI=3.14159; const MyName="Tim"; const Northeast=Vect(1.0,1.0,0.0);
class'Pawn'.const.LargeNumber
오브젝트와 액터 리퍼런스 변수
var actor A; // 액터 리퍼런스 입니다. var pawn P; // Pawn 클래스에 있는 액터에 대한 리퍼런스 입니다. var texture T; // 텍스처 오브젝트에 대한 리퍼런스 입니다.
// 폰을 가리키는 변수를 둘 선언합니다. var pawn P, Q; // P 를 활용하는 함수입니다. // P 에 대한 정보를 조금 표시합니다. function MyFunction() { // P 의 적을 Q 로 설정합니다. P.Enemy = Q; // P 한테 달리기 애니메이션을 재생하라 이릅니다. P.PlayRunning(); }
None
이라는 값을 포함해야 합니다. None 은 C/C++ 의 NULL
포인터에 해당합니다만, UnrealScript 에서는 None
리퍼런스로 함수를 호출하고 변수에 접근해도 안전합니다. 결과는 항상 0 이거든요.
오브젝트나 액터 리퍼런스가 다른 액터나 오브젝트를 "가리킨다" 해도, 그 액터나 오브젝트를 "포함하는" 것은 아님에 유의하십시오. C 에서의 액터 리퍼런스에 해당하는 것은, AActor 클래스에 있는 오브젝트로의 포인터입니다. (C 에서는 AActor* 라 해야겠죠.) 예를 들어 월드에 서로 싸우고 있는 몬스터가 Bob 과 Fred, 둘 있습니다. Bob 의 "Enemy" 변수는 Fred 를 "가리켜야(point to)" 할 것이고, Fred 의 "Enemy" 변수는 Bob 을 "가리켜야" 할 것입니다.
C 포인터와는 달리, UnrealScript 오브젝트 리퍼런스는 항상 안전하고 결코 틀리지 않습니다. 오브젝트 리퍼런스가 존재하지 않거나 (특수한 경우인 None
값을 제외하고는) 무효한 오브젝트를 가리키는 것은 불가능합니다. UnrealScript 에서는 액터가 소멸(destroy)될 때, 그에 대한 모든 리퍼런스는 None
으로 자동 설정됩니다.
리퍼런스를 오브젝트 상호간의 통신을 위해 사용하는 법 관련 자세한 내용은 언리얼스크립트 정석 문서의 스크립트간 통신 부분을 참고하시기 바랍니다.
클래스 리퍼런스 변수
var() class C;
var actor A;
A = Spawn( C ); // 임의의 C 클래스에 속하는 액터를 스폰합니다.
var classActorClass;
// SomeFunctionCall() 결과를 Actor 형 클래스( 또는 Actor 의 서브클래스)로 변환합니다. class( SomeFunctionCall() )
형 변환
묵시적 형 변환
어떤 변수형(일반적으로byte
, int
, float
같은 수치 데이터형)은 서로간의 자동 형 변환이 지원됩니다. 이런 것을 묵시적 형 변환이라 하는데, 데이터 형 변환이 일어나고는 있지만 변환할 유형을 딱 지정하지는 않았기 때문입니다. 묵시적 형 변환은 한 유형의 변수나 값을 다른 유형의 변수에 할당할 때 일어납니다.
예:
var int IntVar; var float FloatVar; ... IntVar = 2; // IntVar 값은 2 입니다. FloatVar = 4.25; // FLoatVar 값은 4.25 입니다. ... IntVar = FloatVar; // IntVar 값은 이제 4 입니다.
FloatVar
와 IntVar
는 유형이 다르지만, int
와 float
서로간에는 묵시적 형 변환을 지원하기 때문에, 하나의 값을 다른 것에 할당할 수 있습니다.
명시적 형 변환
수치형은 묵시적으로 변환 가능한 반면, 다른 유형은 변환시킬 유형을 명시적으로 나타내야 합니다. 명시적으로 선언한다고 다른 모든 유형으로 변환이 가능한 것은 아닙니다. 변환되는 유형은 형 변환 대상이 되는 유형을 지원해야 하며, 그렇지 않으면 컴파일러가 에러를 던집니다. 값을 명시적으로 형 변환할 때, 변환할 유형 뒤 괄호 속에 변환시킬 값을 붙여줘야 합니다. 기본 문법은 이렇습니다:TypeToCastTo(ValueToCast)
String
으로 표시하고픈 Vector
변수가 있다 쳐 봅시다. Vector
데이터형은 String
으로의 형 변환을 지원하므로, 다음과 같은 명령은 완전 유효합니다:
var Vector Offset; var String OffsetText; ... Offset = vect(1.0, 2.5, 5.0); //Offset 값은 이제 X=1.0, Y=2.5, Y=5.0 입니다. OffsetText = String(Offset); //OffsetText 값은 이제 "1.0,2.5,5.0" 입니다.
명시적 형 변환 지원 유형
- String
-
String
데이터형에 지원되는 변환은 다음과 같습니다:- Byte, Int, Float -
String
에 저장된 수치값이 실제 수치값으로 변환됩니다.String
값에 수치가 포함되어 있지 않으면, 형 변환 결과는 그 대상에 따라0
또는0.0
이 됩니다. - Bool -
String
값을TRUE
또는FALSE
로 변환합니다.String
에 (대소문자 상관 없이)"True"
또는"False"
값이 들어 있으면, 텍스트는 그에 맞는Bool
값으로 변환됩니다. 그런 값이 없으면String
값을 먼저 (위에 설명한 규칙에 따라) 숫자 값으로 변환한 다음, 값이0
이면FALSE
로, 그 외의 값이면TRUE
로 해서Bool
값으로 변환합니다. - Vector, Rotator -
Vector
나Rotation
같은 형태(, 쉼표로 구분된 숫자 셋, 예로 "0.5,23.64,18.43")의 텍스트가 들어있는String
을 지정된 대상 데이터형으로 변환합니다.Vector
변환의 경우String
의 숫자 값은 소수점 두 자리Float
로 변환됩니다.Rotator
변환의 경우String
의 숫자 값은 trunc, 소수점 아래를 모두 버리고Int
값으로 변환됩니다.
- Byte, Int, Float -
- Bool
-
Bool
데이터형에 지원되는 변환은 다음과 같습니다:- String -
Bool
의TRUE
또는FALSE
값을 각각"True"
또는"False"
문자열 값으로 변환합니다. - Byte, Int, Float -
Bool
의TRUE
또는FALSE
값을 각각1
또는0
숫자 값으로 변환합니다.
- String -
- Byte, Int, Float, Vector, Rotator
- 이 수치 데이터형에 지원되는 변환은 다음과 같습니다:
- String - 숫자 값을 텍스트 형태로 변환합니다.
Vector
나Rotator
의 텍스트 형태는 숫자 값 셋을 쉼표로 구분한 형태 (X
,Y
,Z
또는Pitch
,Yaw
,Roll
) 입니다. - Bool - 숫자 값을
TRUE
또는FALSE
의Bool
값으로 변환합니다. 0 이외의 값은TRUE
로, 0 은FALSE
로 변환됩니다.Vector
나Rotator
의 경우, 각 성분의 값이 모두 0 이어야FALSE
로 변환됩니다. 0 이외의 값이 있는 경우는TRUE
가 됩니다.
- String - 숫자 값을 텍스트 형태로 변환합니다.
- Name
-
Name
데이터형에 지원되는 변환은 다음과 같습니다:- String -
Name
의 텍스트 값을STRING
텍스트 값으로 변환합니다.
- String -
- Vector
-
Vector
데이터형에 지원되는 변환은 다음과 같습니다:- Rotator - 월드 원점에서
Vector
의 좌표로 지정된 위치까지의 방향을, 그에 맞는Rotator
의Pitch
와Yaw
값으로 변환합니다.Roll
값은 항상0
이 됩니다.
- Rotator - 월드 원점에서
- Rotator
-
Rotator
데이터형에 지원되는 변환은 다음과 같습니다:- Vector -
Rotator
의Pitch
,Yaw
,Roll
값을 원점에서 시작하여 그 로테이션 방향을 가리키는Vector
좌표로 변환합니다.
- Vector -
- Object Reference
-
Object Reference
데이터형에 지원되는 변환은 다음과 같습니다:- Int -
Object Reference
를 고유한Int
값으로 변환합니다. - Bool -
Object Reference
변수에 유효한 리퍼런스가 담겨 있으면TRUE
로,None
이면FALSE
로 변환합니다. - String -
Object Reference
를 텍스트 형태로 변환합니다. 참조되고 있는Object
나Actor
의 (Name
을String
으로 형 변환한 다음)Name
프로퍼티, 또는 참조되고 있는Object
가 없으면"None"
입니다. - Object Reference -
Object Reference
는 두 클래스가 관련되어 있다면, 한 클래스에서 다른 클래스로 변환 가능합니다. 이런 종류의 형 변환 관련 자세한 정보는 오브젝트 리퍼런스 변환하기 부분을 참고하십시오.
- Int -
오브젝트 리퍼런스 변환하기
단순한 데이터형끼리 변환하는 위의 변환 함수와 마찬가지로, UnrealScript 에서도 여러가지 유형의 액터와 오브젝트 리퍼런스를 변환할 수 있습니다. 예를 들어 모든 액터에는 "Target" 이란 이름의 변수가 있는데, 이는 다른 액터로의 리퍼런스입니다. Target 이 "Pawn" 액터 클래스에 속하는지 확인해 봐야 하는 스크립트를 작성한다 칩시다. 그러면 타겟이 폰이어야만 이치에 맞는 특별 작업을 (이를테면 Pawn 함수 중 하나를 호출한다든지) 해 줘야 합니다. 액터 형 변환 연산자로 그 작업을 할 수 있습니다. 예:var actor Target; //... function TestActorConversions() { local Pawn P; // Target 을 Pawn 으로 형 변환하고 결과를 P 에 할당합니다. Target 이 Pawn (또는 그 서브클래스)가 아닌 경우, P 에 할당되는 값은 None 이 됩니다. P = Pawn(Target); if( P != None ) { // Target 이 Pawn 이므로, 그 Enemy 를 Self 로 설정합니다. P.Enemy = Self; } else { // Target 이 Pawn 이 아닙니다. } }
// 소멸되면 엔진에 의해 호출됩니다. function Destroyed() { // 오너의 인벤토리에서 제거합니다. if( Pawn(Owner)!=None ) Pawn(Owner).DeleteInventory( Self ); }