Control units

제어 유닛(Control Units)은 분기(if), 반복문(loop) 그리고 흐름(flow)의 병합기능을 하는 유닛들이다.


Brainching(분기) : If, Swith, Select

분기 유닛(Branching unit)은 값을 기준으로 제어 흐름을 분할한다.

 


< If >


If 유닛은 부울(Boolean) 조건을 사용한다. 그 조건이 "True"일 때 어떤 작업을 진행하고, "False"일 때 다른 작업을 진행하게 된다.


If Unit
If Unit



< Swith >


enum(열거형), string(문자열) 또는 integer(정수) 값에 따라 분기가 되도록 하는 유닛들을 Switch unit이라고 한다.

emnu(열거형)을 switch로 사용하려면 열거형 타입을 선택해야 한다. 그러면 분기 출력 포트가 나타난다.


Switch
Switch

string(문자열) 또는 숫자(number)를 switch로 사용하려면, 그래프 인스펙터에 분기 옵션을 추가해야한다.


Switch
Switch

유닛의 출력 포트에 분기 옵션에 추가한 사항이 반영된다.


Switch Unit
Switch Unit

string(문자열)은 선택자(selector)의 대소문자를 무시하도록 선택할 수도 있다.


참고: Default 포트는 기본적으로 추가되어 있다. 만약, 일치하는 입력 선택자가 없을 경우 제어가 Default로 흘러가게 된다. (역자주-프로그래밍의 switch 문에 default와 동일함)

 


< Select >


Select unit은 Switch unit과 반대다. 선택자의 값에 따라 여러개의 옵션 집합에서 단일 값을 선택하게 된다.

예를 들어 playerNo에 따라 색상을 선택하는 "Select On Integer" 유닛이 있다.


Select On Integer
Select On Integer

참고: 위의 예에서 예측 디버깅(주황색으로 표시되는 경고)은 Default 포트가 연결되어 있지 않기 때문에 playerNo가 1, 2, 3, 4가 아닐 경우 오류가 생기게 됨을 알려주고 있다.



Looping : : While Loop, For Each Loop, For Loop, Break Loop

 

루프(Loop)는 계속 진행하기 전에 일정 횟수만큼 로직(logic)을 반복하는 것이다.

반복되는 로직을 루프의 Body라고 한다. 루프가(반복이) 종료되면 Exit 포트가 호출된다.

 

참고: 모든 루프의 Body는 순차적으로 여러 프레임에 걸쳐 호출되는 것이 아니라 한번에 동시에 호출한다. Coroutine(코루틴)은 업데이트 이벤트를 수동적으로 수신해서 처리하는 방식으로 동작하고 있다.

 


< While Loop >


while loop은 가장 단순한 형태의 루프다. while의 조건이 true인 동안 Body를 반복한다. while조건이 false가 될때 루프가 종료된다.

예를 들어, 다음 그래프는 루프의 결과가 names 변수에 포함되지 않을 때까지(즉, 기존 목록에 없는 새로운 이름이 선택될 때 까지) 새로운 랜덤 name을 생성한다.


While Loop
While Loop


경고: 무한 루프(infinite loop)에 빠지지 않도록 주의 해야 한다. 조건이 항상 True가 되면 무한 루프에 빠지게 된다. 루프 Body가 병렬적(parallel)이지 않고 동시적(synchronous)이기 때문에 비주얼 스크립팅에서는 while loop를 많이 이용하게 되지는 않는다.

 


< For Each Loop >


For Each 문은 컬렉션(collection)의 모든 요소(element)를 반복하게 된다. 현재 루핑 중인 인덱스와 항목을 출력한다.

예를 들어 다음 그래프는 콘솔에 세 개의 메시지를 출력한다.

  • I like cats
  • I like dogs
  • I like birds
For Each Loop
For Each Loop

루프에서 Dictionary의 key와 value로 접근하고자 한다면, Dictionary 체크박스에 체크하면 된다.


 

< For Loop >


For 반복문은 숫자로 구성된 반복문이다. start index, end index 그리고 step 세 개의 정수(integer)가 필요하다. 루프의 시작은 첫 번째 index에서 시작한 다음 step의 크기로 증가하면서 마지막 index까지 반복한다. 출력으로 현재 index를 내보낼 수 있다.

예를 들어, 다음 그래프는 step이 2씩 증가하기 때문에 홀수를 건너뛰며 10까지 진행한다. 즉, 출력은 0, 2, 4, 6, 8이다.


For Loop
For Loop

For 문은 Get List Item, Count Items 유닛과 결합할 때 매우 유용하다.

 

예를 들어, 콘솔에 "I like {animal}s"라고 출력한다는 면에서 For Each Loop의 예시와 매우 유사하다.

Item을 일일이 하나씩 출력하는 대신 List Index를 기준으로 Item을 출력한다. 따라서 증가 값 Setp(여기서는 2)을 지정함으로써 일부 Item은 제외 시킬 수도 있다. 아래의 그래프는 두 개의 메시지를 출력한다.

  • I like cats
  • I like birds
For Loop
For Loop 예시


< Break Loop >


루프는 Break Loop 유닛을 사용하여 반복 중간에 종료 시킬 수 있다. 이 유닛이 실행되자마자 루프는 Exit 포트로 이동한다. 

 

예를 들어, 아래 루프는 10까지 세도록 되어 있지만, Index가 5가 되는 순간 Break 유닛이 실행된다. 따라서 출력은 0, 1, 2, 3, 4만 된다.


Break
Break Loop 사용예


예외 처리(Exception Handling) : Try Catch, Throw


< Try Catch >


Try Catch 유닛은 발생한 예외(Exceptions)를 처리한다. 일부 코드에 오류기 의심될 경우 게임이 크래시(중단)되는 것을 방지할 수 있다.

Try 분기에서 실행되는 모든 작업은 "Safe(안전함)"으로 간주된다. 그리고 스크립트가 실패할 경우 Catch 분기를 통해 오류를 처리하고 계속 실행된다. Exception 포트는 실패에 대한 정보를 전달하는데, 이 정보를 경고 로그로 출력하는 것이 가장 일반적이다. 


Try Catch
Try Catch


참고: 기본적으로 Try Catch 유닛은 모든 예외를 파악(캐치)할 수 있다. 드롭다운에서 처리할 예외(exception) 유형을 변경하면 된다.

Finally 분기는 선택 사항이다. 연산(혹은 처리)가 성공하든 실패하든 상관 없이 항상 Try 또는 Catch 다음에 호출된다. 이는 보통 쓸모 없어진 리소스를 처분하거나 파괴하는데 이용된다. 리소스를 파괴할 필요가 없다면 이 포트는 사용할 필요가 없다.

 


< Throw >


Throw 유닛은 흐름을 멈추게 하는 예외(Exception)를 발생 시킨다. 이 예외를 Try Catch로 처리한다.

 

예상치 못한 일이 발생하면 바로 던짐(throwing)으로써 미리 실패를 확인하는 것은 좋은 습관이다. 이는 버그들이 혼재되고 디버그 하기 어려운 예상치 못한 사이드 이펙트를 발생시키는 대신 초기에 버그를 잡을 수 있도록 하는데 도움이 된다.

 

예를 들어 damage가 양수인지를 보장해야 하는데, 음수가 들어 올경우 Throw로 처리하도록 하는 것이다.


Throw
Throw

Custom 체크박스를 선택을 하면, 단순한 메시지가 아닌 많은 데이터가 포함된 Custom Exception Object를 전달하게 된다. 일반적으로 사용할 일은 거의 없다. 던져진 예외(thrown exception)의 타입은 System.Exception 이다.

 


Toggles(토글) : Toggle Flow, Toggle Value


Toggle 유닛은 전등 스위치와 원리적으로 유사하다. 즉, 스크립트나 값에 따라서 켜지거나 꺼질 수 있다. 문을 비유로 생각한다면 문이 열리거나 닫힌다고 생각하면 된다.

 

< Toggle Flow >


Toggle Flow 유닛은 제어 흐름의 관문과 같다. 켜지(On)면 흐름이 진행되지만, 꺼지(Off)면 흐름이 멈추게 된다. 예를들어 Space 바를 한 번 누르면 움직이기 시작하고 다시 두르면 멈추는 것이다.

 

로직을 제어하는 입/출력은 여러 가지가 있다. 앞의 Space 바 예시에서 Toggle on/Toggle off를 하는데 같은 이벤트(키 누르기)를 이용하였다. 하지만 On/Off를 대신하는 다른 두 개의 이벤트를 통해서도 Toggle이 가능하다. 

 

출력 포트쪽에 있는 "Is On" 불리언 포트는 현재 toggle 상태가 켜져 있는지, 꺼져 있는지를 전달한다. 제어 출력은 아래 테이블에 따라서 전달된다(triggered).


PortTriggered When
OnOn인 상태일 때, 어떤 입력에 대한 제어 처리
OffOff인 상태일 때, 어떤 입력에 대한 제어 처리
Turned OnOn이 된 경우에 대한 제어 처리, 그게 On인데 On이 되었든 Toggle Input이 On이 들어 왔든지 간에
Turned OffOff가 된 경우에 대한 제어 처리, 그게 Off인데 Off가 되었든 Toggle Input이 Off가 들어 왔든지 간에



< Toggle Value >


Toggle Value 유닛은 ON/OFF 여부에 따라 두 개의 입력 값(On Value 또는 Off Value) 중에 어느 하나의 값을 선택한다. 포트의 작동은 Toggle Flow 유닛과 똑같이 동작한다.

앞의 예시를 다른 방법식으로 구현한다면: Space bar를 눌러스 토글을 통해 오브젝트를 움직이거나 멈추게 한다고 할 때, 이번에는 이동 속도(veloctiy)를 On 일 대는 1, Off 일 때는 0의 값을 전달해서 구현하는 것이다.

 

참고: 토글 포트 간의 흐름을 확인하는 방법은 toolbar에서 relations를 켜면 된다.


Toggle Unit
Toggle Units


Once


Once 유닛은 그 이후의 로직을 오직 한 번만 실행한다. (아래 예시는 First Fram이 1회 출력되고 이후 부터는 Following Frames만 반복 출력 된다.)


Once Unit
Once Unit 사용예


Reset 포트를 이용해 재설정할 수도 있다.



Cache

 

Cache 유닛은 값 비싼 연산(계산)을 하고 그 결과를 저장한다. 그리고 이후 다시 필요할 때 재실행하지 않고 바로 재사용할 수 있도록 해준다.

 

예를 들어, 아래와 같이 그래프를 작성하면, Debug.Log가 두 개인데 이를 위해 Formula를 두번 계산하게 된다.


Cache Unit
Cache Unit

Cache 유닛을 사용함으로써 한 번만 계산하고 결과를 저장한 다음 두 번째 Debug.log에서는 계산 없이 바로 사용하게 된다. 이는 성능 최적화를 해준다.


Cache Unit
Cache Unit 사용예

참고: 중요한 것은 Cache는 현재 흐름의 범위에서만 사용가능하다는 것이다.  Cache 값은 다른 이벤트와는 공유되지 않으며 접근할 수도 없다.


 

<원문>

https://docs.unity3d.com/Packages/com.unity.visualscripting@1.7/manual/vs-control.html

댓글

이 블로그의 인기 게시물

EMACS - 파일 열기, 저장, 도움말

EMACS - 검색 및 바꾸기

EMACS, CLISP, SLIME 설치