언리얼 스크립트
변경 목록
사이트 맵
로그인
추적:
•
언리얼엔진3
•
Gears of War 3
•
각주테스트
•
대문
•
blog
이 문서는 읽기 전용입니다. 내용을 볼 수는 있지만, 수정할 수는 없습니다. 문제가 있다고 생각하면 관리자에게 문의하십시오.
====== 언리얼 스크립트 ====== 필수 문법 소개 & 스크립트 버그 소개 & 팁 ===== 구조 ===== ==== Class ==== [[http://www.flickr.com/photos/z3moon/5102096957/|{{http://farm2.static.flickr.com/1077/5102096957_940ff54d32_o.jpg}}]] ==== Property ==== [[http://www.flickr.com/photos/z3moon/5102699128/|{{http://farm2.static.flickr.com/1115/5102699128_ae7eb8c817_o.jpg}}]] ===== 문법 ===== 언리얼스크립트에서 특히나 알아두면 좋은것 몇개 소개해보겠다. ==== 변수 ==== http://wiki.beyondunreal.com/Legacy:UnrealScript_Language_Reference/Variables 참조 ==== 수학함수 ==== <code cpp> float Abs( float A ); // Returns the absolute value of the number. float Sin( float A ); // Returns the sine of the number expressed in radius. float Cos( float A ); // Returns the cosine of the number expressed in radians. float Tan( float A ); // Returns the tangent of the number expressed in radians. float ASin( float A ); // Returns the inverse sine of the number expressed in radius. float ACos( float A ); // Returns the inverse cosine of the number expressed in radius. float Atan( float A ); // Returns the inverse tangent of the number expressed in radians. float Exp( float A ); // Returns the constant "e" raised to the power of A. float Loge( float A ); // Returns the log (to the base "e") of A. float Sqrt( float A ); // Returns the square root of A. float Square( float A ); // Returns the square of A = A*A. float FRand(); // Returns a random number from 0.0 to 1.0. float FMin( float A, float B ); // Returns the minimum of two numbers. float FMax( float A, float B ); // Returns the maximum of two numbers. float FClamp( float V, float A, float B ); // Returns the first number clamped to the interval from A to B. float Lerp( float A, float B, float Alpha ); // Returns the linear interpolation between A and B. float Smerp( float Alpha, float A, float B ); // Returns an Alpha-smooth nonlinear interpolation between A and B. float Ceil ( float A ); // Rounds up float Round ( float A ); // Rounds normally </code> 참조 : https://udn.epicgames.com/Three/UnrealScriptReference ==== 자료구조 ==== * Map<code> // Input.uc var native const Map{FName,void*} NameToPtr; </code> ==== 연산자 ==== 언리얼엔진3 스크립트에 미리 정의된 @, $=, ^ 등의 연산자에 대한 설명 [[http://udn.epicgames.com/Three/UnrealScriptReference.html#Built-in operators and their precedence|UDN 페이지]]를 참조 ===== 정리 ===== 스크립트를 사용하다 보면 다양한 키워드를 볼 수 있는데 여기서는 그 키워드가 어떠한 의미를 가지고 있는지를 정리해두겠다. ==== config vs globalconfig ==== === 의미 === config 와 globalconfig 는 변수 앞에 선언되며 서로 다른 의미를 가진다. 아래의 예제 코드를 보자. <code cpp> // Destination.uc class Destination; var config float Distance; var globalconfig float GlobalDistance; // Seoul.uc class Seoul extends Destination; // Pusan.uc class Pusan extends Destination; </code> Destination 이란 parent class 가 있고 이 안에는 config, globalconfig 속성의 변수가 있다. 그리고 이것을 상속받는 Seoul 과 Pusan class 가 있다. 이 둘의 용법을 가르는 가장 큰 차이는 바로 **[[엔진:언리얼엔진3:Config|설정파일]]에서 값의 override 가능 여부**이다. 풀어서 설명하면 아래와 같다. * config 속성을 가지는 Distance 의 경우 값을 Seoul 과 Pusan 에서 각각 override 할 수 있다. * globalconfig 속성을 가지는 GlobalConfig 의 경우 값을 override 할 수 없다. 즉, Destination 의 값을 그대로 물려받는다. (1 Depth 까지만 물려받는 듯 하다. 2 Depth 부터는 테스트해보질 않아서 장담은 못함) 좀 더 이해를 돕기 위해 속성파일과 코드를 예로 들어보겠다. <code cpp> // Config.ini, 속성파일 [Example.Destination] Distance=20 GlobalDistance=100 [Example.Seoul] Distance=40 GlobalDistance=200 [Example.Pusan] Distance=60 GlobalDistance=300 // MyGameInfo.uc class MyGameInfo extends GameInfo; var Destination Dest; var Seoul Seo; var Pusan Pus; </code> 상기와 같이 Config.ini 라는 설정파일이 있고 MyGameInfo.uc 에서 정의된 게임이 불러지면 * Dest.Distance 는 20, Dest.GlobalDistance 는 100 의 값을 가지고 * Seoul.Distance 는 40, Seoul.GlobalDistance 는 100 의 값을 가지고 * Pusan.Distance 는 60, Pusan.GlobalDistance 는 100 의 값을 가진다. 즉, globalconfig 는 child class 에서 값을 override 할 수 없다. === 코드 === 이를 증명하는 코드는 아래와 같다. <code cpp> // UnObj.cpp void UObject::LoadConfig( UClass* ConfigClass/*=NULL*/, const TCHAR* InFilename/*=NULL*/, DWORD PropagationFlags/*=LCPF_None*/, UProperty* PropertyToLoad/*=NULL*/ ) { ... const UBOOL bGlobalConfig = ( Property->PropertyFlags & CPF_GlobalConfig ) != 0; // GlobalConfig flag 를 알아내고 UClass* OwnerClass = Property->GetOwnerClass(); UClass* BaseClass = bGlobalConfig ? OwnerClass : ConfigClass; // GlobalConfig 라면 OwnerClass 를 취하여 if ( !bPerObject ) { ClassSection = BaseClass->GetPathName(); // Section 이름을 구한다. } ... GConfig->GetString( *ClassSection, *Key, Value, *PropFileName ); // 이런 식으로 Section 이름을 파라메터로 넣어서 설정값을 구한다. ... } </code> ===== 버그 ===== ==== 배열에서 랜덤인덱스 초기화 문제 ==== 언리얼스크립트에서는 초기화되지 않은 배열에 특정 인덱스로 바로 접근하여 value 를 assign 함으로써, 자동으로 배열을 적절하게((접근 index가 배열의 length-1 보다 크다면 배열의 크기를 자동으로 index+1 만큼 늘려준다.)) 늘리고 value 를 assign 해주는 기능이 있다. 이것은 초기화defaultproperties 섹션 안이나, 일반적인 함수function 내부에나 동일하게 동작한다. 하지만 나열자enumerator를 사용하여 배열에 접근할 경우, 초기화defaultproperties는 조금 더 조심스럽게 사용해야 한다. 만약 배열인덱스 접근자인 [ ] 사이에 공백이 들어가게 되면 제대로 초기화되지 않는 문제가 생긴다. 아래 예를 보자. <code cpp> // 다음의 나열자와 enum ENums { E_Num0, E_Num1, E_Num2, E_Num3, E_Num4, E_Num5, E_Num6, ... }; // 다음과 같은 배열이 있다고 가정하고 var Array<int> IntArray; // 다음은 올바른 초기화 섹션의 예이다. defaultproperties { IntArray[E_Num1]=100 // 자동으로 배열 크기를 2로 늘려준 후, 1번 인덱스에 100을 대입 IntArray[E_Num5]=500 // 자동으로 배열 크기를 6으로 늘려준 후, 5번 인덱스에 500을 대입 } // 다음은 틀린 초기화 섹션의 예이다. defaultproperties { IntArray[ E_Num1 ]=100 // 처음은 waning 이 발생하지 않는다. 그러나 0번 인덱스에 100이란 value가 저장된다. IntArray[ E_Num5 ]=500 // 초기화 되지 않고 다음과 같은 wanring 을 내뱉는다. "Warning, redundant data: 블라블라" } </code> 인덱스 접근자 사이에 공백을 넣으면 첫번째 초기화 시점엔 아무런 에러가 나지 않다가((그러나 제대로 초기화 되지 않고 0번 인덱스에 초기화 될 것이다.)) 두번째 시도에 warning을 뱉는다. 위의 경우는 __그나마 warning 이라도 뱉어주니 다른 방법을 모색할 수 있다__. 하지만 다음과 같은 경우는 골때리게도 warning 없이 아주 잘 작동하는 것처럼 보이게 된다. <code cpp> // 다음과 같은 구조체 배열이 있다고 가정하고 struct Nums { var Array<int> IntArray; }; var Nums MyNums; // 다음은 올바른 초기화 섹션의 예이다. defaultproperties { MyNums=(IntArray[E_Num1]=100, IntArray[E_Num5]=500) // 의도한대로 작동할 것이다. } // 다음은 틀린 초기화 섹션의 예이다. defaultproperties { // 역시나 0번 인덱스에 100이란 value가 저장되고 다시 0번 인덱스에 500이란 value가 덮어씌워진다. // 그러나!! warning이 발생하지 않는다. 여기서부터 재앙은 시작된다. MyNums=(IntArray[ E_Num1 ]=100, IntArray[ E_Num5 ]=500) } </code> 나열자enumerator를 사용하지 않고 **바로 숫자를 사용하여 초기화 한다면 위의 경우 문제가 되지 않는다**. 하지만 대부분의 스마트한 프로그래머들은 나열자나 혹은 const형의 특정 변수로 배열을 초기화할 것이기 때문에 위의 경우를 반드시 숙지해두어야 한다. **함수function 내부에서 사용되는 경우 또한 위의 위험에서 안전**하다. 즉, 나열자를 사용하여 접근한다 해도 문제가 되지 않는다. ===== 기타 ===== {{page>엔진:언리얼엔진3:unrealscript빌드}} ==== 스크립트 recompile 여부 판별 ==== 언리얼스크립트를 수정한 후, 게임을 실행하면 스크립트 소스가 최신버전이 아니니 다시 컴파일할 것인지를 물어본다. 이것을 어떤 식으로 판별하는지 알아보자. 이를 수행하는 함수는 AreScriptPackagesOutOfDate (UMakeCommandlet.cpp) 이며 대략적인 시퀀스는 다음과 같다. - 스크립트소스가 있는 경로((Default 로는 ..\..\Development\Src 이며, [UnrealEd.EditorEngine] 섹션 -> EditPackagesInPath 필드로 정의 가능)), 스크립트패키지(.u 확장자의 바이너리) 가 있는 경로((Default 로는 ..\..\UTGame\Script 이며, [UnrealEd.EditorEngine] 섹션 -> EditPackagesOutPath 필드로 정의 가능)), 스크립트패키지 이름 리스트((Core, Engine, GameFramework, UnrealEd, ... 등)) 정보를 얻는다. - 얻어온 스크립트패키지 이름 리스트에서 OnlineSubsystem 으로 시작하는 패키지와 IpDrv 는 제외된다. - 이제 하나의 패키지에 대해서 다음의 내용을 수행한다. - 생성된 패키지의 나이 (파일이 생성된 후로부터 지금까지의 경과 시간) 를 구한다. - 소스가 있는 디렉토리의 나이를 구한다. 이때 디렉토리의 나이는 그 안의 모든 파일들을 순회하며 가장 나이가 적은 놈으로 택한다. - 소스 디렉토리의 나이가 생성된 패키지의 나이보다 적다면, 재컴파일이 필요하다고 판별한다. - ModPackages 에 대해서도 위의 과정을 수행하여 재컴파일 여부를 검사한다. ==== defaultproperties 에서 배열 of 배열 초기화 ==== 다음과 같은 구조가 있다고 치자. <code cpp> struct StructA { var int Cnt; var Vector2D Range; }; struct StructB { var Name Name; var Array<StructA> StructAs; }; var Array<StructB> StructBs; </code> StructBs 은 배열을 가지는 배열인데 이것을 defaultproperties 에서 초기화할 때 다음과 같이 해야한다. (세가지 방법이 있다.) <code cpp> // 1.한줄 표현 defaultproperties { StructBs(0)=(Name="First",StructAs=((Cnt=0,Range=(X=0,Y=1)),(Cnt=1,Range=(X=1,Y=2)))) StructBs(1)=(...) } // 2.여러줄 표현 defaultproperties { StructBs(0)={( Name="First", StructAs=( ( Cnt=0, Range=(X=0,Y=1) ), ( Cnt=1, Range=(X=1,Y=2) ) ) )} StructBs(1)={( ... )} } // 3.여러줄 표현 + 명시적 인덱스 defaultproperties { StructBs(0)={( Name="First", StructAs[0]={( Cnt=0, Range=(X=0,Y=1) )} StructAs[1]={( Cnt=1, Range=(X=1,Y=2) )} )} StructBs(1)={( ... )} } </code> 뒤로 갈수록 보기 쉬워진다는 장점이 있다. from http://wiki.beyondunreal.com/Legacy:Default_Properties 참조 : https://udn.epicgames.com/Three/UnrealScriptDefaultProperties ===== 참조 ===== * https://udn.epicgames.com/Three/UnrealScriptReference * https://udn.epicgames.com/Three/UnrealScriptImplementation * https://udn.epicgames.com/Three/MasteringUnrealScriptVariables * https://udn.epicgames.com/Three/MasteringUnrealScriptIntro * http://wiki.beyondunreal.com/Legacy:Default_Properties {{tag>개발 프로그래밍 엔진 언리얼엔진 스크립트}}
문서 보기
|
이전 버전
|
출력 화면