오버워치 워크샵을 소개합니다!
워크샵으로 기존에는 상상조차 불가능했던 게임을 창조해보세요! 워크샵 내에서는 이미 알고계시는 오버워치의 기존 게임 모드는 물론, 스크립트를 통해 규칙을 추가하고 고유한 플레이 조건을 연출해 볼 수도 있습니다. 여러분이 설정한 규칙으로 영웅의 움직임과 능력을 변경하고, 플레이어의 피해 또는 치유 방식을 바꿔보고, 특정 상황에서 텍스트를 표시하게 할 수도 있습니다.
초고열 불장판이라는 멋진 게임 모드도 만들어볼 수 있습니다. 여기에서는 영웅이 지면에 서 있으면 불에 타오르게 됩니다.
목차
워크샵 사용하기
워크샵을 사용하려면 플레이 > 게임 탐색기 > 만들기 > 설정 > 워크샵을 클릭하시면 됩니다.
스크립트 생성
스크립트를 생성하려면 다음과 같이 하면 됩니다.
이를 통해 허용되는 한 규칙 (Rule), 조건 (Condition), 액션 (Action)을 마음껏 추가할 수 있습니다.
Rule 추가
Rule은 커스터마이징할 수 있는 스크립트 구성 요소입니다. 각 스크립트는 1개 이상의 Rule로 구성됩니다.
각 Rule에는 설명을 남길 수도 있으며, 다음과 같은 내용으로 구성됩니다.
- Event: 해당 Rule이 실행되는 시점을 설정합니다. 자세한 정보는 Event 선택을 참조해주세요.
- Conditions: 이러한 일련의 조건이 참(true)인 경우 Rule이 적용됩니다. 자세한 정보는 Condition 추가를 참조해주세요.
- Actions: Event와 Condition이 부합되었을 때 실행되는 일련의 일들입니다. 자세한 정보는 Action 추가를 참조해주세요.
Rule을 추가하시려면 Rule 추가를 클릭하세요.
Event 선택
Event는 Rule의 실행 시점을 정의합니다. 게임 내에서 Event가 발생하면 Rule의 인스턴스가 생성됩니다. 각 인스턴스는 Condition을 검토하여 인스턴스에 독립적으로 Action을 실행하게 됩니다.
에디터에 Rule이 생성되면 Event가 자동으로 추가됩니다. 어떤 종류의 Event를 원하시는지 지정해 주셔야 합니다.
Event 종류를 설정하려면 다음을 따라주세요.
- Event 옆의 드롭다운 메뉴 클릭.
-
다음 중 하나 택일.
Event 종류 설명 Ongoing - Global 게임 시작 시 이 Rule의 개별 인스턴스 하나를 생성합니다. 이 인스턴스는 게임이 지속되는 동안 활성화되어 있습니다.
- 이 인스턴스는 게임이 지속되는 동안 활성화되어 있으므로 Condition 을 만족하거나 만족하지 않을 수 있습니다. Condition을 처음 만족할 때 Action을 실행 합니다.
- Condition 목록을 만족하지 못했다가 만족한다면, Action을 다시 실행하려 할 것입니다.
Ongoing - Each Player 플레이어가 게임에 참여하면 각 플레이어마다 이 Rule의 인스턴스가 생성됩니다. 이 인스턴스는 해당 플레이어가 게임을 떠나거나, 게임이 끝날 때까지 활성화되어 있습니다. 각 인스턴스는 개별적으로 Condition과 Action을 추적하고 실행합니다.
- 플레이어가 게임에 남아있는 한 인스턴스가 지속되므로 Condition을 만족할 수도, 그렇지 않을 수도 있습니다. Condition을 처음 만족하면Action을 실행합니다.
- Condition 목록을 만족하지 못했다가 만족한다면, Action을 다시 실행하려 할 것입니다.
Player Earned Elimination 플레이어 한 명이 처치를 달성할 때마다 Rule을 실행합니다. 이 Rule은 특정 플레이어를 대상으로 한 번에 하나의 인스턴스만 활성화합니다.
- 플레이어 한 명이 누군가를 처치하면 Condition을 확인합니다. 모든 Condition을 만족하면 Action이 실행되지만, 하나라도 만족하지 않으면 실행되지 않습니다.
Player Dealt Final Blow 플레이어 한 명이 결정타를 날릴 때마다 Rule을 실행합니다. 이 Rule은 특정 플레이어를 대상으로 한 번에 하나의 인스턴스만 활성화합니다.
- 플레이어가 결정타로 피해를 입히면 Condition을 확인합니다. 모든 Condition을 만족하면 Action이 실행되지만, 하나라도 만족하지 않으면 실행되지 않습니다.
Player Dealt Damage 플레이어 한 명이 피해를 입힐 때마다 Rule을 실행합니다. 이 Rule은 특정 플레이어를 대상으로 한 번에 하나의 인스턴스만 활성화합니다.
- 플레이어가 적에게 피해를 주면 Condition을 확인합니다. 모든 Condition을 만족하면Action이 실행되지만, 하나라도 만족하지 않으면 실행되지 않습니다.
Player Took Damage 플레이어 한 명이 피해를 받을 때마다 Rule을 실행합니다. 이 Rule은 특정 플레이어를 대상으로 한 번에 하나의 인스턴스만 활성화합니다.
- 플레이어가 적에게서 피해를 받으면 Condition을 확인합니다. 모든 Condition을 만족하면Action이 실행되지만, 하나라도 만족하지 않으면 실행되지 않습니다.
Player Died 플레이어 한 명이 사망할 때마다 Rule을 실행합니다. 이 Rule은 특정 플레이어를 대상으로 한 번에 하나의 인스턴스만 활성화합니다.
- 플레이어가 사망하면 Condition을 확인합니다. 모든 Condition을 만족할 때 Action이 실행되지만, 하나라도 만족하지 않으면 Action이 실행되지 않습니다.
-
필요한 경우 이 Event의 효력이 발휘되는 대상인 Team 또는 Player를 설정합니다. 옵션은 다음과 같습니다.
옵션 설명 All 개별 전투 모드의 플레이어를 포함한 모든 팀에 Event가 적용됩니다. 1팀 (또는 현재의 팀 이름) 이 팀의 구성원에게만 Event가 적용됩니다. 2팀 (또는 현재의 팀 이름) 이 팀의 구성원에게만 Event가 적용됩니다. 옵션 설명 All Event가 모든 플레이어에게 적용됩니다. Slot 0 ~ Slot 5 Event가 특정 슬롯에 있는 플레이어에게만 적용됩니다. 팀전에서는 플레이어 두 명이 하나의 슬롯 (각 팀 당 하나)을 차지하고 있을 수 있습니다. Slot 6 ~ Slot 11 Event가 특정 슬롯에 있는 플레이어에게만 적용됩니다. 개별 전투 모드에서만 해당됩니다. 특정 영웅 Event가 특정 영웅으로 생성된 플레이어에게만 적용됩니다.
Condition 추가
Rule과 Event를 추가하고 나면 Condition을 하나 이상 추가할 수 있는 옵션이 있습니다. Condition은 Rule에 의해 Action 목록을 실행하기 전 모두 True이어야 하는 조건 목록입니다. Condition이 "Ongoing - Global" 또는 "Ongoing - Each Player" Event 종류를 가진 Rule에 종속된 경우 지속적으로 True인지 확인을 거치게 됩니다. 그 이외 다른 종류의 Rule에 종속된 경우 Event가 발생할 때마다 확인하게 됩니다. 각 Condition은 두 개의 값 (Value)으로 구성되며, 연산자를 사용하여 결과값이 True인지 아닌지 비교 확인 연산에 사용됩니다. 세부 정보는 Values에서 확인 가능합니다.
Condition 추가하는 법:
- Condition 옆에 있는 추가를 클릭합니다.
- 항목 값을 채웁니다.
- 참고: 값 자체가 입력 정보 (Input)를 가지고 있는 경우 (예를 들어 영웅을 얻기 위해 플레이어를 알아야 하는 "Hero Of"), 해당 값의 Input은 그 아래에 따로 표시됩니다.
- 연산자를 선택합니다. 연산자는 다음과 같습니다.
- == 등호
- != 부등호
- > 초과
- >= 이상
- < 미만
- <= 이하
게임 내 모든 플레이어 수가 생존한 플레이어 수와 같은지 여부를 확인합니다.
- Value: "Number of Living Players", 생존한 플레이어 수를 확인합니다.
- Team: Team, 한 팀에 있는 모든 플레이어를 확인합니다.
- Team: All, 모든 팀에 있는 모든 플레이어를 확인합니다.
- 연산자: ==, 이 Condition이 True를 반환하려면 첫 번째와 두 번째 값이 같아야 합니다.
- Value: "Number of Living Players", 생존한 플레이어 수를 확인합니다.
- Team: Team, 한 팀에 있는 모든 플레이어를 확인합니다.
- Team: All, 모든 팀에 있는 모든 플레이어를 확인합니다.
다른 예시
- IsFlagBeingCarried(Victim) == False: 사망한 플레이어는 깃발을 들고 있지 않았어야 합니다.
- IsCrouching(Event Player) == True: 이 Event를 활성화한 플레이어는 웅크리고 있어야 합니다.
- NumberOfFinalBlows(Attacker) > 10: 공격 중인 플레이어는 10번이 넘는 결정타를 달성했어야 합니다.
Action 추가
Action은 게임을 변경하는 인자로, 상위에서 하위로 실행됩니다. Action 목록의 실행은 다음과 같은 경우 시작됩니다.
- Rule과 관련된 Event 발생
- Rule의 모든 Condition이 True (또는 Condition 존재 안 함)
- Event 종류가 "Ongoing - Global" 또는 "Ongoing - Each Player,"인 경우, 각 Condition을 처음 만족할 때 Action 목록이 실행됩니다. Condition 목록을 만족하지 못했다가 만족하는 경우, Action을 다시 실행하려 할 것입니다.
Wait Action(세부 정보는 Wait Action 참조)을 제외한 모든 Action은 즉시 실행 및 종료됩니다. 각 Action은 0 이상의 Input으로 이루어지며, 해당 내용으로 게임을 변화시키게 됩니다. 각 Input은 하나의 값 (Value)을 가지는데, 이는 정보를 얻기 위한 정보 또는 지침입니다. 세부 정보는 Values에서 확인 가능합니다.
Action 추가하는 법:
- Action 옆에 있는 추가를 클릭합니다.
- 게임을 변화시킬 Action을 선택합니다.
- 새로 나타나는 Input마다 드롭다운 메뉴에서 값을 하나 선택합니다.
- 참고: 일부 Action은 오브젝트 또는 Behavior를 생성할 수 있습니다. 그러한 Action의 경우 "Reevaluation"이라는 Input을 가지고 있을 수 있습니다. 이 Input은 이 Action의 다른 Input이 fixed(오브젝트나 Behavior를 변경 안 함)인지 dynamic(Input 변경에 지정된 값대로 오브젝트 또는 Behavior 변경)인지를 결정합니다.
Actions
- Pause Match Time: 현재 경기 시간을 일시 정지합니다
- Modify the Global Variable(T, Add, 5): 전역 변수 (Global Variable) T를 5만큼 증가시킵니다
- Set Invisible(Event Player, Enemies): 이 Rule을 실행시킨 플레이어가 적에게 보이지 않도록 합니다
Reevaluation Input이 있는 Action
- Create Icon(All Players(All Teams), Global Variable(P), Alert, Position): Global Variable "P"가 지정한 위치에 있는 모든 이들이 식별 가능한 경고 아이콘을 생성합니다. 해당 위치 (Position)는 지속적으로 재연산 되므로 나중에 Global Variable "P"가 변경되면 아이콘 위치도 새로운 위치로 변경됩니다.
- Create Icon(All Players(All Teams), Global Variable(P), Alert, None): Global Variable P가 지정한 위치에 있는 모든 이들이 식별 가능한 경고 아이콘을 생성합니다. 아무것도 재연산하지 않으므로 나중에 Global Variable P가 변경되어도 이 아이콘의 위치를 업데이트하지 않습니다.
Action 종류
Action은 많기는 하지만, 알아두셔야 할 Action은 소수입니다:
Loop는 Action 목록을 처음부터 재시작하는 Action으로, 네 가지 종류가 있습니다.
- Loop: 항상 Action 목록을 재시작합니다
- Loop If: 해당 Action의 Condition Input 값이 0이나 False가 아닌 값으로 재연산 되는 경우 Action 목록을 재시작합니다
- Loop if Condition Is True: 해당 Rule의 모든 Condition을 만족하면 Action 목록을 재시작합니다
- Loop If Condition Is False: 해당 Rule의 Condition을 하나라도 만족하지 않으면Action 목록을 재시작합니다
Loop Action은 Action 목록 시작 전에 Wait Action이 존재하는 경우에만 허용됩니다.
바람직한 경우 | 바람직하지 않은 경우 |
---|---|
Loop 전에 Wait가 가능하므로 허용됩니다. |
Wait 없이 무한으로 실행되므로 허용되지 않습니다. |
Wait는 이후 Action을 실행할 때까지 시간이 흐르도록 두는 Action입니다. 최소 대기 시간은 0.25초입니다.
Wait Action에는 세 가지 Behavior 옵션이 있습니다.
- Ignore Condition: 이것을 선택하면 Condition이나 다른 Event로 Action 실행을 중지할 수 없습니다.
- Event 종류가 "Ongoing - Global" 또는 "Ongoing - Each Player"인 경우, Condition 만족 여부에 관계 없이 아무 일도 일어나지 않습니다.
- Event가 다른 종류고 해당 종류가 동일한 Event Player에게 발동되는 경우, 해당 Event는 완전히 무시됩니다.
- Abort When False: 이것을 선택하면 Condition을 만족하지 못하는 시점에서 Action 목록 실행이 중지됩니다.
- Restart When True: 이것을 선택하면 다음과 같은 일이 일어나는 경우 Action 실행 시 첫 Action을 재시작합니다.
- Event 종류가 "Ongoing - Global" 또는 "Ongoing - Each Player"이며, Condition을 만족하지 못한 상태에서 만족한 상태로 바뀌는 경우.
- Event가 다른 종류고, Event가 동일한 Event Player에게 발동되며, Condition을 전부 만족하는 경우.
추가 정보
String은 게임 내 표시될 수 있는 문자, 숫자, 기호의 배열입니다.
String 값은 문자열을 생성하며 다음과 같은 Input을 가집니다:
- String: 표시할 텍스트입니다. 텍스트에 중괄호 안의 숫자가 있는 경우, 관련 Input의 값으로 대체됩니다.
- {0}: String 내의 {0}을(를) 대체하기 전에 텍스트로 전환되는 값입니다. 이 값은 어떤 종류라도 상관없습니다.
- {1}: String 내의 {1}을(를) 대체하기 전에 텍스트로 전환되는 값입니다. 이 값은 어떤 종류라도 상관없습니다.
- {2}: String 내의 {2}을(를) 대체하기 전에 텍스트로 전환되는 값입니다. 이 값은 어떤 종류라도 상관없습니다.
- String(“Hello”, Null, Null, Null): “Hello” 문자열을 생성합니다
- String(“{0} vs {1}”, Hero(Ana), Hero(Pharah), Null): “Ana vs Pharah” 문자열을 생성합니다
String은 결합하여 더 복잡한 문자열이 될 수 있습니다.
- String(“{0} vs {1}”, Hero(Ana), String("{0} and {1}", Hero(Pharah), Hero(Genji), Null), Null): “Ana vs Pharah and Genji” 문자열을 생성합니다
동일한 사용자 지정 게임에서 다른 언어를 사용하는 플레이어가 존재하는 경우 혼란을 겪을 수 있으므로, String은 Condition에 사용하거나 변수 (Variables)로 저장할 수 없습니다.
값 (Value)은 정보이거나 정보를 얻을 수 있는 지침으로, Condition, Action, 또는 다른 값의 Input으로 제공됩니다. 여러 값이 결합할 수도 있습니다.
무궁무진하게 많은 값이 있으므로 여기에서 모두 정의하지는 않겠지만, 워크샵 에디터에서 보실 수 있습니다. 여기 그 일부를 소개합니다.
Value | 설명 |
---|---|
Number | Input에서 정의한 범위의 실수를 제공합니다 |
Vector | Input에서 정의한 범위의 3차원 값을 제공합니다. 위치 및 방향으로 쓰입니다 |
Team | 특정 팀을 뜻합니다. (1팀, 2팀, 전체 팀) |
Hero | 특정 영웅을 뜻합니다 |
Null | 플레이어 또는 개체가 없음을 뜻합니다 |
True | 참 (True) 값을 제공합니다 |
False | 거짓 (False) 값을 제공합니다 |
Compare | 비교 결과에 따라 True 또는 False를 제공합니다 |
Event Player | 해당 Rule의 인스턴스를 실행 중인 플레이어를 제공합니다. 그러한 플레이어가 없는 경우 Null을 제공합니다 |
Attacker | 해당 Rule의 인스턴스의 공격자를 제공합니다. 공격자가 없는 경우 Null을 제공합니다 |
Victim | 해당 Rule의 인스턴스의 피해자를 제공합니다. 피해자가 없는 경우 Null을 제공합니다 |
Current Array Element | If True For Any, If True For All, Filtered Array, 또는 Sorted Array Value와 함께 쓰이는 현재 값을 제공합니다 |
하나의 값은 여러 값의 집합체인 배열 (Array)에 저장될 수 있습니다.
- 일련의 Action 및 값으로 Array를 생성하거나 변경할 수 있습니다.
- 예를 들어 "All Players" 값으로는 게임 내 모든 플레이어가 담긴 Array 하나를 얻을 수 있습니다.
- "Modify Global Variable" Action 또는 "Modify Player Variable" Action의 "Append To Array" 기능으로 자신만의 Array를 구성해볼 수도 있습니다.
- Input은 Array를 요구하지만 다른 형태의 값을 받는 경우, 해당 값은 편의상 하나의 요소로 구성된 Array에 복사됩니다. 마찬가지로 Input은 다른 형태의 값을 요구하지만 Array를 받는 경우, 해당 Array의 첫 값(또는 Array가 비어있는 경우 0)이 사용됩니다.
변수 (Variable)는 값을 저장하여 나중에 회수할 수 있는 공간입니다. 변수에는 String 외의 어떤 값도 저장할 수 있습니다. 모든 변수는 0이라는 숫자(Number)값으로 시작합니다.
스크립트에서는 두 가지 종류의 변수가 있습니다.
- 전역 변수 (Global Variable): A부터 Z까지로 이름 지어진 26개의 Global Variable이 있으며, 각 변수는 각각 값 또는Array를 가지고 있습니다.
- 플레이어 변수 (Player Variable): 각 플레이어는 A부터 Z까지로 이름 지어진 26개의 변수를 가지고 있으며, 각 변수는 각각 값 또는 Array를 가지고 있습니다.
변수 내에서 세 가지 연산이 가능합니다.
- Setting: "Set Global Variable"과 "Set Player Variable"을 통해 변수가 가지고 있던 값을 새로운 값으로 설정합니다.
- Modifying: "Modify Global Variable"과 "Modify Player Variable"은 특정 사칙연산 (Add, Multiply 등) 또는 Array 연산(Append, Remove)을 통해 변수 내 값을 변경합니다.
- Chasing: "Chase Global Variable Over Time", "Chase Player Variable Over Time", "Chase Global Variable at Rate", "Chase Player Variable at Rate"을 통해 변수를 시간이 지남에 따라 조금씩 바꾸거나 특정 비율로 변경할 수 있습니다.
- Chase의 목표치는 숫자 또는 Vector 값(또는 숫자나 Vector가 도출되는 값)일 수 있습니다.
- 목표치가 숫자라면 변수값은 Chase 시작 전에 숫자가 되어야 Chase가 정상 작동합니다.
- 목표치가 Vector라면 변수값은 Chase 시작 전에 Vector가 되어야 Chase가 정상 작동합니다.
- 목표치 Reevaluation을 사용하는 경우, Chase는 목표치에 도달한 적이 있더라도 필요 시 업데이트를 통해 변경된 목표치를 따라가게 됩니다. Reevaluation에 대한 세부 정보는 Action 추가에서 확인해주세요.
- "Stop Chasing Global Variable" Action과 "Stop Chasing Player Variable" Action으로 Chase를 취소할 수 있습니다.
- Chase가 취소되면 변수는 Chase 시작 전의 원래값과 목표치 사이의 현재값을 지니게 됩니다.
- Chase의 목표치는 숫자 또는 Vector 값(또는 숫자나 Vector가 도출되는 값)일 수 있습니다.
예시
이제 뭔가 재미있는 것을 해볼까요? 아래 게임 모드 중 하나를 만들어보세요! 그 과정에서 무엇을 왜 넣어야 하는지 알려드리겠습니다.
영웅이 지면을 디디는 경우 화염에 휩싸여 피해를 받게 되는 초고열 불장판을 어떻게 만들 수 있는지 차근차근 알려드리겠습니다.
- 우선 원하는 전장으로 게임을 플레이할 수 있도록 설정하겠습니다.
- 플레이 > 게임 탐색기 > 만들기 > 설정 > 전장을 클릭합니다.
- 게임을 테스트했으면 하는 전장을 선택한 후 다른 모든 전장은 비활성화합니다.
- 다음으로 워크샵에 들어갑니다.
- 뒤로를 클릭합니다.
- 워크샵을 클릭합니다.
- 이제 스크립트를 만들 시간입니다! 첫 번째 규칙을 추가해보죠.
- Rule 추가를 클릭합니다.
- 설명 부분에 지면을 밟으면 불이 붙음 (Start Burning If On Ground )이라고 입력합니다. 그러면 이 설명을 보고 플레이어가 지면에 닿는 경우 불타오른다는 사실을 알 수 있습니다.
- 이제 Event 종류를 변경하여 이 Rule이 언제 실행될지를 알 수 있도록 합니다.
- Event 드롭다운 메뉴에서 Ongoing - Each Player를 선택합니다. 이렇게 되면 해당 Rule은 게임 내에서 각 플레이어마다 개별로 연산 되게 됩니다.
- 다른 드롭다운 메뉴는 기본 옵션으로 남겨둡니다.
- 이제 Condition을 추가해보겠습니다. Condition을 통해 해당 Rule을 실행할지 여부를 결정하게 됩니다. 해당 Rule이 항상 실행되기를 원하신다면 이것을 비워두시면 됩니다!
- Condition 아래의 추가를 클릭합니다.
- 첫번째 Value 드롭다운 메뉴에서 Is On Ground를 선택합니다. 이 값은 플레이어가 지면에 있으면 True가 됩니다.
- 다른 드롭다운 메뉴는 기본 옵션으로 남겨두고 확인을 클릭합니다.
- Event Player란 “해당 Rule이 현재 적용되고 있는 플레이어”를 말합니다.
- 마지막으로 Action을 추가합니다. Action은 Condition이 True일 경우 실행됩니다.
- 이 Action은 영웅이 지면에 있는 경우 불타오르게 만들 것입니다.
- Actions 아래의 추가를 클릭합니다.
- Action 드롭다운 메뉴에서 Set Status를 선택합니다.
- Status 드롭다운 메뉴에서 Burning을 선택합니다.
- Duration 아래의 Number슬라이더를 10,000으로 변경합니다.
- 다른 드롭다운 메뉴는 기본 옵션으로 남겨두고 확인을 클릭합니다.
- 이 Action은 영웅이 지면에 있는 경우 불타오르게 만들 것입니다.
- 이제 영웅이 지면에 있으면 불타오르는지 시험해보죠!
- 뒤로를 두 번 클릭합니다.
- 게임 만들기 화면에서 시작을 클릭합니다.
- 영웅을 선택합니다.
- 게임에 들어가자마자 영웅이 불타오를 것입니다.
- Esc를 누르고 워크샵 에디터 열기를 클릭하여 계속 스크립트를 짜보죠.
- 이제 영웅이 공중으로 점프하는 경우 불에 타지 않는 규칙을 추가해보겠습니다.
- 시작부터 새 Rule을 추가하는 대신 마지막으로 생성한 것을 복사해보겠습니다.
- 생성한 Rule 옆에 있는 복사 를 클릭합니다.
- Rule 붙여넣기를 클릭합니다.
- 설명을 공중에 있으면 불이 꺼짐 (Stop Burning When In the Air)으로 변경합니다. 이 Rule로 영웅이 공중에 있거나 점프할 경우 불에 타지 않는다는 것을 상기시켜 줄 것입니다.
- Event 종류는 유지합니다.
- 이제 Condition을 편집해 보겠습니다. Condition을 통해 해당 Rule을 실행할지 여부를 결정하게 됩니다.
- 기존의 Condition인 "Is On Ground(Event Player) == True"를 클릭합니다.
- Value 드롭다운 메뉴에서 False를 선택합니다.
- 다른 드롭다운 메뉴는 기존 옵션으로 남겨두고 확인을 클릭합니다.
- 다음으로는 Action을 편집해보겠습니다. 이 Action은 영웅이 지면에 없는 경우 더 이상 불타오르지 않도록 할 것입니다.
- 기존 Action 중 "Set Status (Event Player, Null, Burning, 10000)" 을 클릭합니다.
- Action 드롭다운 메뉴에서 Clear Status를 선택합니다.
- Status 드롭다운 메뉴에서 Burning을 선택합니다.
- 다른 드롭다운 메뉴는 기존 옵션으로 남겨두고 확인을 클릭합니다.
- 생성한 Rule 옆에 있는 복사 를 클릭합니다.
- 시작부터 새 Rule을 추가하는 대신 마지막으로 생성한 것을 복사해보겠습니다.
- 그럼 영웅이 공중에 있는 경우 불이 꺼지는지 시험해 보죠!
- 뒤로를 두 번 클릭합니다.
- 게임에 들어가자마자 영웅이 불타오를 것입니다. 점프하면 불이 꺼지는지 확인해 봅니다.
- Esc를 누르고 워크샵 에디터 열기를 클릭하여 계속 스크립트를 짜 보죠.
- 마지막으로, 영웅이 지면에 있을 때 피해를 주도록 하겠습니다.
- "Start Burning If On Ground" Rule을 확장합니다.
- Action 아래의 추가를 클릭합니다. 이 Action은 영웅이 지면에 있을 때 피해를 받도록 할 것입니다.
- Action 드롭다운 메뉴에서 Start Damage Over Time을 선택합니다.
- Duration 아래의 Number 슬라이더를 9999로 변경합니다.
- Damage Per Second 아래의 Number 슬라이더를 30으로 변경합니다.
- 다른 드롭다운 메뉴는 기본 옵션으로 남겨두고 확인을 클릭합니다.
- "Stop Burning If Not On Ground" Rule을 확장합니다.
- Action 아래의 추가를 클릭합니다. 이 Action은 영웅이 지면에 없을 때 피해를 더 이상 받지 않도록 할 것입니다.
- Action 드롭다운 메뉴에서 Stop All Damage Over Time을 선택합니다.
- 영웅이 지면에 있을 때는 피해를 받고, 공중 또는 점프 중일 때는 피해를 받지 않는지 시험해 보겠습니다.
- 뒤로를 두 번 클릭합니다.
- 전투준비실을 나와 영웅이 피해를 받기 시작하는지 확인합니다.
- 점프하면 영웅이 피해를 받지 않는지 확인합니다.
- 해내셨습니다! 이제 지면은 용암이 되었습니다!
미러전 데스매치는 좀더 심화된 게임 모드입니다. 이 모드에서는 전원이 동일한 영웅을 플레이하는 짧은 라운드가 여러 차례 진행됩니다. 각 라운드가 종료되면 각 플레이어는 일정 목록 내 무작위 선택된 다음 영웅으로 원위치에서 부활합니다. 마지막 라운드가 종료되면 처치 수가 가장 많은 플레이어가 승리합니다.
예를 들어 한 경기에서 모두들 맥크리로 시작했다가 다음 라운드에서 파라로 바꿔 플레이하게 됩니다. 다른 경기에서는 위도우메이커로 시작했다가 다음 라운드에서 애쉬로 바꿔 플레이하게 됩니다. 생성된 목록대로 플레이하기 때문에 영웅을 동일한 순서로 플레이하게 될 가능성은 희박합니다!
자, 그럼 미러전 데스매치의 스크립트를 준비해 보죠!
- 플레이 > 게임 탐색기 > 만들기 > 설정 > 워크샵을 클릭합니다.
- 우선 플레이 예정인 영웅 목록을 만드는 Rule을 생성해보겠습니다.
- 목록은 Array로 Global Variable "L"에 저장됩니다.
- Array는 플레이어 목록, 영웅 목록, 숫자 목록, 하나의 값, 또는 아무 값이 아닐 수도 있는("비어 있는" Array) 등 뭐든 될 수 있습니다.
- Array에 저장된 각각의 값은 0에서부터 오름차순의 고유 인덱스로 저장됩니다. 하나의 인덱스와 그 값은 요소라고 지칭되기도 합니다.
- Array의 순서는 중요합니다.
[Reaper, Winston, Mercy]
는[Mercy, Winston, Reaper]
와 서로 다른 Array입니다. - Array에는 서로 다른 종류의 값이 있을 수 있습니다. 예를 들어
]123, Reaper, True, -4.5]
라는 Array도 가능합니다. - Input이 기다리던 Array 형태가 아닌 단일 값 (single Value)이 제공되는 경우, 해당 Input은 이 단일 값을 요소 하나를 가진 Array로 받아들이게 됩니다.
- Input이 기다리던 단일 값이 아닌 Array를 받는 경우, 해당 Input은 Array의 첫 값(또는 Array가 비어있는 경우 0)을 받아들이게 됩니다.
- Rule을 추가하고 설명을 넣어서 이 Rule이 무슨 기능인지 알 수 있도록 합니다.
- Event 종류를 Ongoing - Global로 설정합니다. 이 Rule의 인스턴스 하나만 실행한다는 의미입니다.
- 이 Rule은 Condition이 없으므로 게임이 시작하자마자 실행될 것입니다.
- 다음과 같이 Action 추가
- Action: Set Global Variable
- Variable: L
- Value: Hero
- Hero: 플레이 가능하도록 하고 싶은 영웅입니다.
- Action: Set Global Variable
- 목록은 Array로 Global Variable "L"에 저장됩니다.
-
이렇게 하면 영웅 Array가 생성됩니다. "Set Global Variable" Action을 통해 "L"을 목록의 첫 영웅으로 설정합니다.
- 게임에서 오직 하나의 영웅만 가능한 경우 지루할 수 있으니 더 추가해 보겠습니다! 다음과 같이 Action을 원하는 만큼 추가합니다.
- Action: Modify Global Variable
- Variable: L
- Operation: Append
- Value: Hero
- Hero: 플레이 가능하도록 하고 싶은 영웅입니다.
- Action: Modify Global Variable
-
이렇게 "L"에 만들었던 영웅 Array에 영웅을 추가합니다. 첫 Action이 "Set Global Variable" 대신 "Modify Global Variable"로 시작했다면, Array는 0부터 시작할 것입니다. 모든 변수는 기본값이 0이므로 설정을 변경하지 않으면
[0, Pharah, Hanzo, Ana,...]
와 같은 Array를 얻게 됩니다. - 이 Rule의 마지막 Action을 추가해 보겠습니다. 이 Rule은 Global Variable L(영웅 Array)의 무작위 복사본을 이용하여 0번 위치에서 시작하는 무작위 Array의 일부를 복사해 해당 게임 모드에 필요한 수의 영웅을 추가합니다. 이 복사본은 다시 Global Variable L로 저장됩니다. 여러분이 제공한 원본 영웅 목록이 무작위로 뒤섞인 부분 집합이 된 것입니다.
- 예) 초기 영웅 목록이
[Ashe, Doomfist, Hanzo, McCree, Pharah, Soldier: 76, Zenyatta, Widowmaker, Ana]
였다면, 무작위화 된 Array는[Hanzo, Pharah, Widowmaker, Ana, Ashe, Doomfist, Soldier: 76, Zenyatta, McCree]
가 되며, 그 일부는[Hanzo, Pharah, Widowmaker, Ana, Ashe, Doomfist]
가 됩니다.
- 예) 초기 영웅 목록이
- 다음 Rule은 무슨 일이 있더라도 모든 플레이어가 언제든 동일한 영웅을 플레이하도록 보장합니다.
- Rule을 추가하고 설명을 넣어서 이 Rule이 무슨 기능인지 알 수 있도록 합니다.
- Event 종류를 Ongoing - Each Player로 설정합니다. 각 플레이어는 각자의 Rule 인스턴스를 실행한다는 뜻입니다.
- 두 개의 Condition을 추가합니다. 전부 True인 경우 다음과 같이 영웅을 강제합니다.
- 라운드 수인 Global Variable "R"이 영웅 목록에 있는 영웅의 총 수보다 작아야 합니다. 그렇지 않으면 게임이 종료되고 더 이상 영웅을 지정할 수 없기 때문입니다. 라운드 수는 0에서 시작해 증가하니 6 라운드로 진행한다면 마지막 라운드는 5입니다. 모든 변수는 기본값이 0이니 Global Variable "R"은 0으로 설정하지 않아도 됩니다.
- Value: Global Variable
- Variable: R
- 연산자: <
- Value: Count Of
- Array: Global Variable
- Variable: L
- Array: Global Variable
- Value: Global Variable
- 이를 통해 특정 플레이어가 현재 플레이하는 영웅이 해당 라운드에 지정된 영웅과 다른지를 확인합니다. "특정 Player"는 현재 Rule 인스턴스를 실행한 플레이어라는 뜻의 특별 값인 Event Player로 사용합니다. 해당 라운드에 "지정된 영웅"은 영웅 목록(Global Variable "L")의 관련 인덱스에 대응하는 영웅입니다. 현재 라운드는 Global Variable "R"에 저장되어 있으므로 지정된 영웅은 "Value In Array"를 사용해 얻을 수 있습니다.
- Value: Hero Of
- Player: Event Player
- 연산자: !=
- Value: Value in Array
- Array: Global Variable
- Variable: L
- Index: Global Variable
- Variable: R
- Array: Global Variable
- Value: Hero Of
- 라운드 수인 Global Variable "R"이 영웅 목록에 있는 영웅의 총 수보다 작아야 합니다. 그렇지 않으면 게임이 종료되고 더 이상 영웅을 지정할 수 없기 때문입니다. 라운드 수는 0에서 시작해 증가하니 6 라운드로 진행한다면 마지막 라운드는 5입니다. 모든 변수는 기본값이 0이니 Global Variable "R"은 0으로 설정하지 않아도 됩니다.
- 플레이어가 영웅을 변경해야 하므로 다음과 같은 작업을 수행하는 Action 두 개를 추가합니다.
- 첫 Action은 Event Player에게 지정된 영웅을 배정합니다. 이 Action의 첫 Input은 영웅을 배정받는 플레이어입니다. 두 번째 Input은 영웅이므로 영웅을 지정합니다.
- Action: Start Forcing Player To Be Hero
- Player: Event Player
- Hero: Value In Array
- Array: Global Variable
- Variable: L
- Index: Global Variable
- Variable: R
- Array: Global Variable
- 두 번째 Action은 목록 상의 다음 영웅을 미리 불러와서 플레이어가 영웅 교체 시 오래 대기하지 않도록 합니다. 각 플레이어는 전원이 동일한 영웅을 플레이한다고 해도 영웅을 개별적으로 미리 불러오는데, 이는 각 플레이어가 해당 영웅의 다른 스킨을 미리 불러와야 하는 경우가 있기 때문입니다. 값 추가로 Global Variable "R"에 1을 더하면 Action이 현재 영웅 대신 다음 영웅을 미리 불러옵니다. 그런데 이렇게 되면 마지막 라운드에서는 Array Global Variable "L"이 허용하는 범위 밖의 Array 인덱스가 사용됩니다. Array에서 허용하는 범위 밖의 값은 0으로 간주되므로 문제는 없습니다. 영웅을 기다리고 있는 Action이 0을 받게 되면 아무것도 하지 않기 때문입니다.
- Action: Preload Hero
- Player: Event Player
- Hero: Value In Array
- Array: Global Variable
- Variable: L
- Index: Add
- Value: Global Variable
- Variable: R
- Value: Number
- Number: 1.00
- Value: Global Variable
- Array: Global Variable
- 첫 Action은 Event Player에게 지정된 영웅을 배정합니다. 이 Action의 첫 Input은 영웅을 배정받는 플레이어입니다. 두 번째 Input은 영웅이므로 영웅을 지정합니다.
- 새로운 Rule을 설정하여 시작하지 않은 라운드를 준비합니다.
- Rule을 추가하고 설명을 넣어서 이 Rule이 무슨 기능인지 알 수 있도록 합니다.
- Event 종료를 Ongoing - Global로 설정합니다. 이 Rule의 인스턴스 하나만 실행한다는 의미입니다.
- 세 개의 Condition을 추가합니다. 전부 True인 경우 라운드가 시작합니다.
- 게임이 진행 중이어야 합니다. 좀 더 구체적으로 설명하자면 영웅 선택 화면과 준비 시간은 이미 지났지만, 게임이 종료되지는 않은 단계라는 뜻입니다.
- Value: Is Game In Progress
- 연산자: ==
- Value: True
- Global Variable I은 False이어야 합니다. 이 변수는 현재 라운드가 시작되었는지 여부를 알기 위해 사용합니다. Global Variable I가 설정되지 않았으면 False에 준하는 0 값을 가지고 있을 것입니다.
- Value: Global Variable
- Variable: I
- 연산자: ==
- Value: False
- Value: Global Variable
- 라운드 수인 Global Variable "R"은 영웅 목록에 있는 총 영웅 수보다 적어야 합니다.
- Value: Global Variable
- Variable: R
- 연산자: <
- Value: Count Of
- Array: Global Variable
- Variable: L
- Array: Global Variable
- Value: Global Variable
- 게임이 진행 중이어야 합니다. 좀 더 구체적으로 설명하자면 영웅 선택 화면과 준비 시간은 이미 지났지만, 게임이 종료되지는 않은 단계라는 뜻입니다.
- Condition이 전부 True이면 라운드를 시작해야 합니다. Action 몇 개를 추가해서 이러한 작업을 수행합니다.
- 첫 Action은 경기가 일반적인 기준으로 종료되어서는 안 된다고 코어 게임 모드에게 알려주어야 합니다. 데스매치의 경우, 시간이 다 되었거나 누군가 제한 점수에 도달했다고 해서 경기가 종료되지 않는다는 의미입니다. 이 Action이 실행되면 스크립트가 게임 모드 종료 체계를 다시 활성화하거나 승자가 정해지지 않는 한 경기가 종료되지 않습니다.
- Action: Disable Built-in Game Mode Completion
- 다음 Action으로 게임 모드의 현재 타이머를 라운드 길이만큼으로 설정합니다.
- Action: Set Match Time
- Time: Number
- Number: 60.00
- 이 Action은 Global Variable "I"를 True로 설정하여 Global Variable "I"가 다시 False로 설정되지 않는 한 시작되지 않도록 합니다.
- Action: Set Global Variable
- Variable: I
- Value: True
- 첫 Action은 경기가 일반적인 기준으로 종료되어서는 안 된다고 코어 게임 모드에게 알려주어야 합니다. 데스매치의 경우, 시간이 다 되었거나 누군가 제한 점수에 도달했다고 해서 경기가 종료되지 않는다는 의미입니다. 이 Action이 실행되면 스크립트가 게임 모드 종료 체계를 다시 활성화하거나 승자가 정해지지 않는 한 경기가 종료되지 않습니다.
- 이 Rule은 다음 라운드로 진행하기 전에 현재 라운드의 시간이 소요되기를 기다립니다.
- Rule을 추가하고 설명을 넣어서 이 Rule이 무슨 기능인지 알 수 있도록 합니다.
- Event 종료를 Ongoing - Global로 설정합니다. 이 Rule의 인스턴스 하나만 실행한다는 의미입니다.
- 두 개의 Condition을 추가합니다. 전부 True인 경우 다음 라운드로 진행합니다.
- 게임이 진행 중이어야 합니다. 좀 더 구체적으로 설명하자면 영웅 선택 화면과 준비 시간은 이미 지났지만, 게임이 종료되지는 않은 단계라는 뜻입니다.
- Value: Is Game In Progress
- 연산자: ==
- Value: True
- 현재 경기 시간은 0이어야 합니다. 0은 라운드 시간이 만료되었다는 뜻입니다.
- Value: Match Time
- 연산자: ==
- Value: Number
- Number: 0.00
- 게임이 진행 중이어야 합니다. 좀 더 구체적으로 설명하자면 영웅 선택 화면과 준비 시간은 이미 지났지만, 게임이 종료되지는 않은 단계라는 뜻입니다.
- 이러한 Condition이 True이고 라운드가 종료되면 경기 라운드 수가 증가하며, 해당 라운드는 시작되지 않았다고 표시합니다. 이를 위해서 Action 두 개를 추가합니다.
- 이 Action은 다른 Rule에게 경기가 다음 라운드로 진행된다는 사실을 알립니다.
- Action: Modify Global Variable
- Variable: R
- 연산자: Add
- Value: Number
- Number: 1.00
- 이 Action은 Global Variable "I"를 False로 놓아 다른 Rule에게 다음 라운드가 시작되어야 한다는 사실을 알립니다.
- Action: Set Global Variable
- Variable: I
- Value: False
- 이 Action은 다른 Rule에게 경기가 다음 라운드로 진행된다는 사실을 알립니다.
- 모든 라운드를 플레이하면 마지막 Rule로 경기가 종료되게 합니다.
- Rule을 추가하고 설명을 넣어서 이 Rule이 무슨 기능인지 알 수 있게 합니다.
- Event 종료를 Ongoing - Global로 설정합니다. 이 Rule의 인스턴스 하나만 실행한다는 의미입니다.
- 하나의 Condition을 추가합니다. Global Variable "R"이 Global Variable "L"에 있는 요소의 수와 같은지를 확인하기 위함입니다. 만약 같다면 영웅 목록에 있는 각 영웅으로 라운드를 진행했다는 뜻입니다. 이 경우 경기는 종료되어야 합니다.
- Value: Global Variable
- Variable: R
- 연산자: ==
- Value: Count Of
- Array: Global Variable
- Variable: L
- Array: Global Variable
- Value: Global Variable
- Condition이 True면 이 Action은 게임 모드 종료 체계를 다시 활성화할 것입니다. 타이머가 0일 것이므로 게임 모드는 즉시 경기를 종료하고 일반적인 경기 종료 과정이 시작될 것입니다.
- Action: Enable Built-in Game Mode Completion
스크립트 디버깅
스크립트를 만들면 워크샵 인스펙터로 게임 내에서 스크립트 실행 현황을 확인하고 어떤 Action과 Condition이 활성화되었는지, 그리고 스크립트에 어떤 문제가 있는지도 확인해 볼 수 있습니다.
워크샵 인스펙터 사용하는 법:
- 생성하신 스크립트로 게임을 시작합니다.
- Esc를 누릅니다.
- 워크샵 인스펙터 열기를 누릅니다.
- 활성화를 누릅니다. 이 기능은 기본적으로 비활성화 상태입니다.
워크샵 인스펙터는 몇 가지 요소로 구성되어 있습니다.
- Entry: Entry을 통해 무슨 일이 일어나는지 확인할 수 있습니다.
- Comment: 해당 Rule과 관련된 설명을 표시합니다.
- Condition: Action 실행을 위해 충족되어야 하는 Condition 목록입니다.
- Action: 실행되는 Action 목록입니다.
- 시간대 조절 슬라이더: 시간대 조절 슬라이더로 게임 진행 시점을 앞뒤로 조절할 수 있습니다.
스크립트 공유
멋진 스크립트를 만드셨다면 6개월 간 누구에게나 (또는 친구끼리만) 공유할 수 있습니다. 스크립트를 생성하신 플랫폼에 관계 없이 모든 플랫폼에서 사용 가능합니다.
스크립트를 공유하는 방법은 다음과 같습니다.
- 플레이 > 게임 탐색기 > 만들기 > 설정 > 공유를 클릭합니다.
- 복사를 클릭합니다.
- 코드를 다른 사람들에게 보내보세요!
스크립트 열기
누군가 쓸만한 스크립트를 보내줬다면 다음과 같이 하시면 됩니다.
- 플레이 > 게임 탐색기 > 만들기 > 설정 > 임포트를 클릭합니다.
- 코드를 입력합니다.
- 확인을 클릭합니다.
팁과 노하우
- 단축키를 지정하시면 워크샵 인스펙터 사용이 훨씬 수월해집니다. Esc > 설정 > 조작법을 클릭하시고 ‘워크샵 인스펙터 열기’까지 스크롤을 아래로 내린 후 단축키를 지정하세요.
- 워크샵 인스펙터는 발생한 일은 물론, 발생하지 않은 일(및 그 이유)까지 알려드립니다!
- 간편 설정 게임이 있다는 것도 잊지 마세요! 손수 새로운 해결책을 강구할 필요 없이 이미 제공된 설정을 사용할 수도 있습니다.
- Event가 제대로 시작되지 않는다면 Event Player가 이미 Action 목록을 실행 중이기 때문일 수 있습니다. Rule의 Wait Action을 확인해보세요. 특히 Condition을 무시하는 설정이 되어있는지는 않은지 잘 살펴보세요.
- 전장에서 특정 위치를 선택하려면 "Vector" 값을 사용해야 하며, 카메라 아이콘을 클릭해야 합니다.
- 경기 내에서 플레이어가 영웅을 선택했는지 논리적 확인을 해야 할 때는 "Has Spawned" 값이 유용합니다.
- 게임 준비 및 영웅 선택 단계 이후 여러분의 Rule만 실행되었으면 하는 경우에는 "Is Game In Progress" 값을 사용하세요.
- 변수에 값을 배정하고 워크샵 인스펙터로 살펴보면 게임플레이 중 어떤 값이 되돌아오는지 아주 쉽게 살펴볼 수 있습니다.
- "Last Created Entity" 값을 사용하면 마지막으로 생성한 효과 또는 아이콘을 Player Variable에 저장할 수 있습니다. 이를 통해 나중에 해당 개체를 참조하여 제거할 수 있습니다.
- 필터링된Array를 "All Players On Objective" 또는 "Players Within Radius"와 같은 값과 섞어 쓰면 특정 기준 (사망, 생존, 상태 효과 등)에 부합하는 플레이어를 쉽게 필터링할 수 있습니다.
- 여러 진행 경로로 Behavior를 설정할 필요가 있는 경우, "Skip If" Action을 사용하면 주어진 Condition이 True일 때 원하는 수만큼의 Action을 건너뛸 수 있습니다. 이 경우 양쪽 경로 모두에서 진행이 되는 것을 막기 위해, 건너뛴 Action에 "Abort" Action을 넣어주어야 할 수 있습니다.
- 알파벳 문자를 입력하여 드롭다운 목록에서 필터링할 수 있습니다.
- 매개 변수로 Array를 받지 못한 경우, Input을 단일크기의 Array에 넣을 것입니다.
- 그 반대도 마찬가지입니다. 값이 단일 데이터가 아닌 Array를 받은 경우, 해당 Array의 0 위치에 있는 요소를 사용할 것입니다.
- 스크립트를 여러 개의 Action과 Condition으로 나누어 구성하면 어디에서 문제가 발생했는지 더 쉽게 알 수 있습니다.
- Action, Value, Input의 용도를 이해하기 어렵다면 PC에서는 마우스 오버해 보시거나, 콘솔에서는 " 상세 정보 보기"를 선택해 관련 정보를 확인해 보세요.
- 해당 Rule이 어떤 용도인지 잊지 않도록 설명 항목은 항상 기재하세요!
- 자주 테스트해보세요!