База модов


Популярные моды




Создание рычага открывающего двери

Я хотел сделать урок по навмешам, но решил поговорить о скриптах, так как видел мало уроков по ним.
В этом уроке мы создадим рычаг со скриптом, который открывает одну из трех дверей.
Этот урок для профи, но думаю и новички, что то почерпнут из него.

Что ж начнём.

В игре в принцепи все рычаги одинаковые, но мы возьмём двемерский рычаг, ID - (DweLever01)

Рис.1




В окне визуализации или предварительного просмотра, кто как называет, в общем я думаю если вы читаете такой урок вы должны знать такую мелочь.
Как мы видим, рычаг в центральном положении указывает прямо вверх. Однако, как только он будет загружен в игре, положение по умолчанию будет изменено, оставшись с правой стороны. У рычага есть анимация и эти анимации можно изменить с помощью скрипта и функции:

PlayAnimation.

В окне визуализации мы видим внизу, что у рычага есть шесть анимаций:

1.PushDown
2.PushUp
3.FullPush
4.PullDown
5.PullUp
6.FullPull


Что бы увидеть это информацию, нужно просто открыть окно визуализации и нажать на рычаг в активаторах.

И так же есть два события анимации:

1.FullPushedUp
2.FullPulledDown


События вам не надо искать, это просто две стрелки, которые поворачивают или вправо рычаг или влево.

Анимация происходит, когда мы потянули рычаг вправо, или задвинули влево.
Я объясню подробней:
Анимации:

1."PushDown" используется для перемещения рычага из среднего положения в левое положение.
2."PushUp" для перемещения слева в середину.
3."FullPush" для перемещения слева направо.
4."PullDown" используется для перехода от среднего положения направо.
5."PullUp" для перехода от права к середине.
6."FullPull" для перемещения справа налево.

Теперь, когда мы знаем, как анимация рычага работает, мы можем приступить к созданию скрипта для него.

Начинаем создание скрипта:


Этот урок рассчитан на продвинутых модмейкеров, которые уже умеют работать со скриптами, тех кто не понимает этого, прошу прекратить прочтение данного урока и изучать мат. часть. Тут я не буду упоминать такие мелочи как прикреплять скрипт к объекту, как перетащить объект в мир и подобное.

В скрипте, в начале должно быть extends, чтобы расширить ObjectReference, потому что рычаг будет иметь ссылки на объекты. Таким образом, наша первая строчка скрипта должно выглядеть так:

Scriptname (ID скрипта) extends ObjectReference

Вы также можете поместить свои комментарии в фигурные скобки, чтобы описать то, что делает скрипт. Комментарии в фигурных скобках

появляются при наведении курсора мыши на скрипт в Creation Kit.

Пример:

Scriptname (ID скрипта) extends ObjectReference

{Скрипт, который будет активировать одну из трех дверей, в зависимости от положения рычага.}


Properties and Variables (Свойства и переменные)


Затем вы должны задать свойства и переменные. Хотя это и не так обходимо в начале создания вашего скрипта, но всё же я объясню.

Свойства.


Как и имя скрипта, вы также можете поместить комментарии в фигурных скобках для свойства так, что бы они появлялись при наведении

курсора на данный скрипт в Creation Kit. Эти свойства, мы поставим в наш скрипт:

ObjectReference property Door01 auto
{Первая дверь, ее можно активировать.}


ObjectReference property Door02 auto
{Вторая дверь, ее можно активировать.}


ObjectReference property Door03 auto
{Последняя дверь, ее можно активировать.}


Так же позже мы кажем ссылка на эти двери в Properties, но позже.

Переменные.

После свойств, мы можем объявить наши переменные:

Int LeverPosition = 1
;Текущее положение рычага.

Int LeverPositionOld
;Предыдущие положение рычага.


Мы будем использовать эти переменные для отслеживания положений рычага. Вы могли заметить, что переменная "LeverPosition" отличается от "LeverPositionOld".

Мы присвоили значение по умолчанию "LeverPosition". Это означает, что даже прежде, чем что-либо произойдёт, значение "LeverPosition" уже будет изменено на 1, а значение по умолчанию 0.

Положение рычага по умолчанию используется с правой стороны. Так что мы должны указать это в нашем скрипте, и начальное значение LeverPosition будет 1. В нашем скрипте мы будем менять значения этих двух переменных -1, 0, 1 много раз. Значение 1 означает, поворот (в право), 0 будет означать среднее положение, и -1 повернуть в позицию (слева).

Со свойствами и переменными мы разобрались. Сейчас мы переходим на фактическую работу скрипта.

Events and Functions (События и функции)


Обычно события и функции ставятся в случайном порядке, на самом деле без разницы, в конце они или в начале, но для урока я поставлю

всё по порядку, а т.е в начале.

Функции


Давайте начнем с определения наших функций.

Код
Function SetDefaultState()
   
  if (LeverPosition == 1)
  PlayAnimation("PullUp")
  elseif (LeverPosition == -1)
  PlayAnimation("PushUp")
  endif
  LeverPositionOld = LeverPosition
  LeverPosition = 0
  OpenDoor()
   
EndFunction


Имя функции "SetDefaultState", и мы будем использовать её много раз. Цель функции заключается в перемещении рычага в среднее

положение.

if (LeverPosition == 1)

Используется для проверки, находится ли рычаг в положении 1 (повернут вправо).

PlayAnimation("PullUp")

Если это так, строка сообщает команду для перемещения рычага обратно в среднее положение.

PlayAnimation("PullUp")

Точно так же проверяется, если рычаг находится в положении -1 (сдвинут влево) и возвращает его в среднее положение.

Код
elseif (LeverPosition == -1)
  PlayAnimation("PushUp")
endif


Дальше рассмотрим, OpenDoor строку вызова функции, что в принципе мы собираемся внести в скрипт дальше.

*******************
Если вы хотите понять скриптиг лучше, вы должны понять структуру IF-ENDIF ElseIf-это некая проверочная система. Начинается с начало "if", чтобы проверить, истинно ли условие. Если истинно, то каждая строка после "if" выполняется, если не верно,то ставится либо "ElseIf" или "ENDIF"."ElseIf" условно не является обязательным. Это полезно, если вы хотите проверить на новых условиях, когда вы знаете, что предыдущая строка не соответствуют действительности. Как и у "if", если условие "ElseIf" истинно, то все строки после него, выполняются, перед тем как вы придете к другому "ElseIf" или "ENDIF".
"ENDIF" используется, чтобы завершить выполнение всех IF-ENDIF ElseIf-структур.
********************

Для каждого "if", вы должны иметь "ENDIF", либо скрипт не будет компилироваться!

Это наша следующая функция:

Код
Function DisableDoors()
   
  Door01.BlockActivation()
  Door02.BlockActivation()
  Door03.BlockActivation()
   
EndFunction


Функция DisableDoors используется, когда мы хотим отключить активацию дверей. Использование BlockActivation запретит открытие двери, хотя вы все же увидите подсказку: открыть дверь. Есть и другие команды, которые мы могли бы использовать, чтобы быстро отключить активацию, но я попытаюсь использовать самое простое.

Код
Function CloseDoors()
   
  if (Door01.GetOpenState() != 3)
  Door01.SetOpen(false)
  endif
  if (Door02.GetOpenState() != 3)
  Door02.SetOpen(false)
  endif
  if (Door03.GetOpenState() != 3)
  Door03.SetOpen(false)
  endif
   
EndFunction


Функция CloseDoors используется, когда мы хотим убедиться, что все двери закрыты. В этой строке if (Door01.GetOpenState() != 3) мы проверяем, не закрыта ли дверь Door01 (значит открытая) с помощью GetOpenState.
В следующей строке Door01.SetOpen(false) мы закрываем дверь с помощью SetOpen. Мы делаем то же самое для двух других дверей.

Код
Function OpenDoor()
   
  if (LeverPosition == -1)
  Door01.SetOpen()
  elseif (LeverPosition == 0)
  Door02.SetOpen()
  else
  Door03.SetOpen()
  endif
   
EndFunction


Функция OpenDoor заключается в том, что бы правильно открывать двери на основе текущего положения рычага. Если рычаг находится в положении -1 (слева) он откроет Door01. Если это среднее положение, то Door02. И если это не в одной из этих позиций, он откроет Door03.

События


События представляют собой вещи, которые происходят в игре. Когда событие происходит, скрипт получает уведомление об этом, и если есть код, написанный в скрипте с событием, то оно будет осуществляться.

Код
Event OnReset()
  SetDefaultState()
  DisableDoors()
EndEvent


Здесь мы видим код события OnReset. Скрипт обрабатывает событие, когда происходит перезапуск объекта,скрипта,либо ячейки.
Когда событие получено, скрипт выполняет две функции, которые мы создали ранее, SetDefaultState и DisableDoors.

Код
Event OnLoad()
  SetDefaultState()
  DisableDoors()
EndEvent


Далее мы рассмотрим событие OnLoad. Мы сделаем в нём то же самое, что и в OnReset событии.

Код
Auto State Inactive
   
  Event OnActivate(ObjectReference akActivateRef)
   
  GoToState("Active")
  CloseDoors()
  if (LeverPosition != 0)
  SetDefaultState()
  else
  if (LeverPositionOld == 1)
  PlayAnimation("PushDown")
  LeverPosition = -1
  else
  PlayAnimation("PullDown")
  LeverPosition = 1
  endif
  LeverPositionOld = 0
  OpenDoor()
  endif
  Utility.Wait(1)
  GoToState("Inactive")
   
  EndEvent
   
EndState
   
   
State Active
EndState


А теперь мы подошли к заключительной части нашего скрипта, событию OnActivate. Это событие будет получено, когда кто-то пытается активизировать наш рычаг.

Вы можете быть удивлены, видя новые положения. Я не уверен, что могу точно описать их, так что это, вероятно, лучше просто проверить.

Проще говоря, все скрипты/объекты имеют положения.Если нет определенных событий в сценарии, объект находится в "нулевом" положении.

В нашем скрипте, у нас было

Auto State Inactive
;Действия
EndState


Auto - здесь означает, что наш объект будет автоматически переведен в "неактивное" состояние, когда он загружается."Действия" между двух строк выполняются только тогда, когда рычаг находится в неактивном состоянии.

Таким образом, вы можете видеть, что если рычаг находится в «активном» состоянии, при попытки активировать его он ничего не делает.

Обратите внимание, что все функции и события, которые находятся в "активном" или "неактивном" состоянии (то есть они находятся в нулевом состоянии) доступны из любого состояния.

Теперь давайте взглянем на код события OnActivate. Эта событие GoToState("Active") игра сообщает рычагу, который сейчас находится в «активном» состоянии, как только мы его активировала. Это не значит, что скрипт будет прекращать обработку остальной части кода в "неактивном" состоянии, это просто означает, что последующая активация не будет обрабатывать код.

Код
CloseDoors()
if (LeverPosition != 0)
  SetDefaultState()


Если вы следовали тому, что я писал, всё должно получиться. Мы указываем функцию CloseDoors, чтобы убедиться все двери закрыты.

Если рычаг не находится в среднем положении, мы меняем его в среднее положение.

Код
else
  if (LeverPositionOld == 1)
  PlayAnimation("PushDown")
  LeverPosition = -1
  else
  PlayAnimation("PullDown")
  LeverPosition = 1
  endif
  LeverPositionOld = 0
  OpenDoor()
endif


Если предыдущее состояние было не такое, то рычаг должен был в среднем положении. Где мы проверяем нашей переменной LeverPositionOld , предыдущую позицию. Очевидно, что мы не хотим, переключать рычаг от права, в середину и назад направо. Так что, если старые положения рычага были 1 (право), то теперь перейдут в левое положение. Если у вас было -1 (слева), всё в правильном положении.

Затем мы устанавливаем значение LeverPositionOld до 0, и указываем функцию OpenDoor.У нас не было этих двух событий после if (LeverPosition != 0) потому что они уже являются частью функции SetDefaultState.

Наш последний кусок кода

Utility.Wait(1)
GoToState("Inactive")


говорит о том, чтобы подождать 1 секунду (для того, чтобы проиграть анимацию), а затем вернуться в "неактивное" состояние (так что активация рычага еще раз сделает что-то).

Заключение


И так это всё, теперь составляем скрипт вместе и ваш скрипт должен выглядеть примерно так:

Код
Scriptname (ID скрипта) extends ObjectReference

{Скрипт, который будет активировать одну из трех дверей, в зависимости от положения рычага.}
   
;;;;;;;;;;;;;;;;
;; Свойства;;
;;;;;;;;;;;;;;;;
   
ObjectReference property Door01 auto
{Первая дверь, ее можно активировать.}
   
ObjectReference property Door02 auto
{Вторая дверь, ее можно активировать.}
   
ObjectReference property Door03 auto
{Последняя дверь, ее можно активировать.}
   
   
;;;;;;;;;;;;;;;;;;;
;;Переменные ;;
;;;;;;;;;;;;;;;;;;;
   

Int LeverPosition = 1
;Текущее положение рычага.Здесь мы устанавливаем его значение по умолчанию 1.
   
Int LeverPositionOld
;Предыдущие положение рычага.

   
   
;;;;;;;;;;;;;;;;;
;; Функции ;;
;;;;;;;;;;;;;;;;;
   
Function SetDefaultState()
   
  if (LeverPosition == 1)
  PlayAnimation("PullUp")
  elseif (LeverPosition == -1)
  PlayAnimation("PushUp")
  endif
  LeverPositionOld = LeverPosition
  LeverPosition = 0
  OpenDoor()
   
EndFunction
   
   
Function DisableDoors()
   
  Door01.BlockActivation()
  Door02.BlockActivation()
  Door03.BlockActivation()
   
EndFunction
   
   
Function CloseDoors()
   
  if (Door01.GetOpenState() != 3)
  Door01.SetOpen(false)
  endif
  if (Door02.GetOpenState() != 3)
  Door02.SetOpen(false)
  endif
  if (Door03.GetOpenState() != 3)
  Door03.SetOpen(false)
  endif
   
EndFunction
   
   
Function OpenDoor()
   
  if (LeverPosition == -1)
  Door01.SetOpen()
  elseif (LeverPosition == 0)
  Door02.SetOpen()
  else
  Door03.SetOpen()
  endif
   
EndFunction
   
   
;;;;;;;;;;;;;;;
;;События ;;
;;;;;;;;;;;;;;;
   
Event OnReset()
  SetDefaultState()
  DisableDoors()
EndEvent
   
   
Event OnLoad()
  SetDefaultState()
  DisableDoors()
EndEvent
   
   
Auto State Inactive
   
  Event OnActivate(ObjectReference akActivateRef)
   
  GoToState("Active")
  CloseDoors()
  if (LeverPosition != 0)
  SetDefaultState()
  else
  if (LeverPositionOld == 1)
  PlayAnimation("PushDown")
  LeverPosition = -1
  else
  PlayAnimation("PullDown")
  LeverPosition = 1
  endif
  LeverPositionOld = 0
  OpenDoor()
  endif
  Utility.Wait(1)
  GoToState("Inactive")
   
  EndEvent
   
EndState
   
   
State Active
EndState


Теперь сохраните свои скрипт. Теперь вы можете применить его, поставив рычаг где-то, дважды щелкнув по нему, чтобы изменить его, и перейти к его самой правой закладке. Вы должны удалить два скрипта, которые уже находятся на нем, и заменить их на скрипт, который вы только что написали. Это должно выглядеть примерно так:

Рис.2



После добавления вашего скрипта, нажмите кнопку ОК, чтобы закрыть окно и теперь разместите три двери. После того как вы сделали это, вернитесь к рычагу и его вкладке со скриптом снова. Щелкните правой кнопкой мыши по скрипту и выберите пункт Свойства. Теперь вам надо просто установить ссылки на Door01, Door02 и Door03 к дверям, которые вы хотите открыть / закрыть.

Рис.3



Вот и все! Сохраните ваш мод и проверьте его в игре.

Всем спасибо!

Урок переведён Фантомом.Копирование запрещено!
Фантом
Посетители
Всего материалов: 309
9 310
0
Всего комментариев: 2
  1. Побольше видео уроков biggrin
    4 июня 2015 13:44 Like | 0
  2. Прикольно biggrin
    4 июня 2015 13:43 Like | 0
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.