Разберем небольшие анимационные скрипты которые вам полюбасу, друзья мои, на жизненном пути понадобятся.
Это скрипты открывания-закрывания ворот. Что происходит в момент поднятия опускания решетки? меняются координаты объекта.
Эти изменения и фиксируются скриптом.
begin coolscript
float timer
short On
short Open
if (MenuMode == 0)
if (OnActivate == 1)
if (On == 0)
set timer to 0
set On to 1
"ex_PM_portcullis_01"->PlaySound3D, "Door Metal Open"
endif
endif
endif
if (On == 1)
set timer to timer + GetSecondsPassed
if (Open == 0)
if (timer < 1)
"ex_PM_portcullis_01"->MoveWorld z, -340
elseif (timer >= 1)
set On to 0
set Open to 1
endif
elseif (Open == 1)
if (timer < 1)
"ex_PM_portcullis_01"->MoveWorld z, 340
elseif (timer >= 1)
SetatStart
set On to 0
set Open to 0
endif
endif
endif
endif
end coolscript
Это скрипт написанный для крепости, обратите внимание на поведение ворот. Анимация подчиняется таймеру. Почему? потому что на ее выполнение нужно время. Координата в которой меняется значение - z, потому что ворота опускаются и поднимаются. думаю это понятно. В данном случае - опускаются.
Поэтому стоит число со знаком минус. По проществии какого то времени они позвращаются в исходное положение. Этот скрипт должен висеть собственно на кнопке или рычаге. Следует прикрутить и звук, хотя я не полагаю это сверхобязательным.
А вот классический скрипт из игры висящий на Призрачных вратах. Более сложный.
Begin PM_OpenGate1
float timer
short state
if ( MenuMode == 1 )
return
endif
if ( OnActivate == 1 )
if ( GG_Gate1_State == 0 )
PlaySound "Open Lock"
"ex_PM_portcullis_01"->Playsound3DVP "Dwemer Door Open" 1.0 1.0
set GG_Gate1_State to 10
set state to 10
endif
endif
if ( State >= 10 )
set timer to ( timer + GetSecondsPassed )
;move gate up (210 units)
if ( timer < 3 )
"ex_PM_portcullis_01"->MoveWorld z -340
;set back to start
elseif ( timer > 21 )
"ex_PM_portcullis_01"->SetAtStart
set State to 0 ;can now press button again
set GG_Gate1_State to 0
set timer to 0
;move gate down (210 units)
elseif ( timer > 18 )
;use state so sound only plays once
if ( State == 10 )
"ex_PM_portcullis_01"->Playsound3DVP "Dwemer Door Open" 1.0 1.0
Set State to 20
endif
"ex_PM_portcullis_01"->MoveWorld z 340
endif
endif
end PM_OpenGate1
На призрачных вратах две кнопки, одна опускает первую пару ворот, вторая - вторую. Из комментариев видно, что до некоторого момента ворота нельзя активировать снова.
Подъем ворот можно повесить и на невидимый активатор который будет вычислять, насколько близко вы подошли. И автоматически открывать дверь - как в некоторых магазинах. Такое можно увидеть в плагине EJ12- "имени Скального наездника". Причем там вычисляется любое шевеление рядом, а выглядит как бы защитой от монстров.
Рассмотрите в учебнике примеры плавающих объектов. Так же там есть вопросы передвижения объектов в мире - это уже посложнее просто анимации, хорошие скрипты на эту тему отработаны в Ultimate Galleon и рыбацкой академии ( правда - в обработке Ковбоя, который отдебажил процесс, не позволяя плееру проваливаться сквозь статик.)
На стр 53 вы так же можете посмотреть скрипты вращения объектов. А зачем это? В плагинах где есть предметы декорации - должна быть и возможность поставить украшение так как надо - в том числе возможно вращая его - например чтобы тарелка на камине стояла наклонно к стенке. Или ковер висел как надо даже если стена стоит к оси мира под неправильным углом. Примеры скриптов позиционирования весьма многочисленны. Вот классический скрипт от Pekka и Dracus
Begin _WAR_Pek_Dracus_script
; посмотрите на количество переменных. Плавающие переменнные нужны для действий вроде вращения. Каждая для определенного вида движения и для каждой
из осей!
Short OnPCDrop
Short ReallTimeRotation
Short controlvar
Short button
Short activate_menu
Short increments
Short lockit
Short angle_increments
Float ScaleIncrements
Float currxangle
Float curryangle
Float currzangle
Float currxpos
Float currypos
Float Currscale
Float startxangle
Float startyangle
Float startzangle
Float currzpos
Float startxpos
Float startypos
Float startzpos
;----------------------------------------------------------
;(Script originally made by Dracus. Extended by Pekka.)
;(Dracus comments are within # and Pekka's within -.)
;Pekkas version: 0.03b
;----------------------------------------------------------
;----------------------------------------------------------
;Trying to lock the object to the ground when dropped,
;repeating Dracus OnActivate Script.
;(A shame we cant make proper functions)
;----------------------------------------------------------
If ( OnPCDrop == 1 )
Set OnPCDrop To 0 ; переменные приравниваются к функциям для последующего действия, чтобы не болтались под ногами.
Set increments To 1
Set angle_increments To 1
Set ScaleIncrements To 0.05
Set activate_menu To 1
Set controlvar To 1
Set startxpos To GetPos, x
Set startypos To GetPos, y
Set startzpos To GetPos, z
Set startxangle To GetAngle, x
Set startyangle To GetAngle, y
Set startzangle To GetAngle, z
Set currxpos To GetPos, x
Set currypos To GetPos, y
Set currzpos To GetPos, z
Set currscale To GetScale
;(Probably completely Unescesary but It should be locked
;untill the menu gets activated
Set lockit To 1
Set Activate_menu To 0
Set controlvar To 0
EndIf
;---------------------------------------------------------------
;If rotation is set to on, the first part will make it to rotate.
;Else the rotation stops with 2. We optimize the script and lag
;a bit less when we direct set it to 0 I hope. (pekka)
;---------------------------------------------------------------
If ( ReallTimeRotation == 1 )
Rotate x 30
Rotate y 30
Rotate z 30
ElseIf ( ReallTimeRotation == 2 )
Rotate x 0
Rotate y 0
Rotate z 0
Set ReallTimeRotation To 0
EndIf
;--------------------------------------------------------
;I turned following check off as we should be able to put
;crystals outdoor and adjust them outdoor as well.
;(Pekka)
;--------------------------------------------------------
;
;########################################################
; If we're outside, there's no need for this script at all
;########################################################
;
;If (GetInterior == 0) ; определяется, находится ли игрок в помещении.
; return
;endif
;########################################################
; This code makes sure that the object acts like a regular item
; that you can pick up and place in your inventory while
; in menu mode
;########################################################
If ( MenuMode == 1 )
If ( OnActivate == 1 )
Activate
Set lockit To 0 ; определяется было ли открыто меню и надо ли его закрыть
EndIf
Return
EndIf
;########################################################
; If controlvar = -1 means the player selected the "Take" option
; in the menu and lets you pick up the item
;########################################################
If ( controlvar == -1 )
Activate
Set controlvar To 0 ; завершение скрипты при выборе игроком кнопки Взять предмет.
Set lockit To 0
Return
EndIf
;#######################################################
;Locks the painting position back in place
;Fixes a problem with the positioned objec;Locks the painting position back in placet going back to where
;you dropped it after you load a savegame;Fixes a problem with the positioned object going back to where
;There's no way to know when the game is loaded that I know.
;I set the variable "lockit" to 1 whenever the painting is positioned
;When it is set to 1 this piece of code checks
;to see if the object is out of place and puts;When it is set to 1 this piece of code checks it back where it's
;supposed to be.
;#######################################################
If ( lockit == 1 )
If ( GetPos, z != currzpos ) ; сбросить изменения
SetPos, x, currxpos
SetPos, y, currypos
SetPos, z, currzpos
Return
ElseIf ( GetPos, y != currypos )
SetPos, x, currxpos
SetPos, y, currypos
SetPos, z, currzpos
Return
ElseIf ( GetPos, x != currxpos )
SetPos, x, currxpos
SetPos, y, currypos
SetPos, z, currzpos
Return
EndIf
If ( GetScale != Currscale )
SetScale, Currscale
EndIf
EndIf
;################################################################
; End of Lock check
;################################################################
;######################### Starting Menu ############################ поехали кнопки.
If ( OnActivate == 1 )
;if (GetInterior == 0)
; Activate
; set lockit to 0
; return
;endif
Set increments To 1 ; приводим все в боевую готовность. Все вещи со сброшенными пока данными.
Set angle_increments To 1
Set ScaleIncrements To 0.05
Set activate_menu To 1
Set controlvar To 1
Set startxpos To GetPos, x
Set startypos To GetPos, y
Set startzpos To GetPos, z
Set startxangle To GetAngle, x
Set startyangle To GetAngle, y
Set startzangle To GetAngle, z
Set currxpos To GetPos, x
Set currypos To GetPos, y
Set currzpos To GetPos, z
Set currscale To GetScale
ElseIf ( controlvar == 0 )
Return
Set lockit To 0
EndIf
If ( activate_menu == 1 )
MessageBox "Меню", "Взять", "Повернуть", "Разместить", "Вращать", "Масштаб", "Ничего"
Set activate_menu To 0
Set lockit To 0
EndIf
If ( controlvar == 1 )
Set button To GetButtonPressed
If ( button == -1 )
Return
ElseIf ( button == 0 )
Set controlvar To -1
Set activate_menu To 0
Return
ElseIf ( button == 1 )
Set controlvar To 2
Set activate_menu To 2
ElseIf ( button == 2 )
Set controlvar To 3
Set activate_menu To 3
ElseIf ( button == 3 )
Set controlvar To 4
Set activate_menu To 4
ElseIf ( button == 4 )
Set controlvar To 5
Set activate_menu To 5
Else
Set controlvar To 0
Set activate_menu To 0
Set lockit To 1
Return
EndIf
EndIf
;######################## Rotation Menu ###################################
If ( activate_menu == 2 )
If ( angle_increments == 1 )
MessageBox "Вращение", "Повернуть на 1", "Вращать X", "Вращать Y", "Вращать Z", "Сбросить", "Восстановить", "Назад"
ElseIf ( angle_increments == 5 )
MessageBox "Вращение", "Повернуть на 5", "Вращать X", "Вращать Y", "Вращать Z", "Сбросить", "Восстановить", "Назад"
ElseIf ( angle_increments == 45 )
MessageBox "Вращение", "Повернуть на 45", "Вращать X", "Вращать Y", "Вращать Z", "Сбросить", "Восстановить", "Назад"
Else
MessageBox "Вращение", "Повернуть на 90", "Вращать X", "Вращать Y", "Вращать Z", "Сбросить", "Восстановить", "Назад"
EndIf
Set activate_menu To 0
EndIf
If ( controlvar == 2 )
Set currxangle To GetAngle, x
Set curryangle To GetAngle, y
Set currzangle To GetAngle, z
Set button To GetButtonPressed
If ( button == -1 )
Return
ElseIf ( button == 0 )
If ( angle_increments == 1 )
Set angle_increments To 5
ElseIf ( angle_increments == 5 )
Set angle_increments To 45
ElseIf ( angle_increments == 45 )
Set angle_increments To 90
Else
Set angle_increments To 1
EndIf
Set activate_menu To 2
Return
ElseIf ( button == 1 )
Set currxangle To ( currxangle + angle_increments )
If ( currxangle >= 360 )
Set currxangle To ( currxangle - 360 )
EndIf
SetAngle, x, currxangle
Set activate_menu To 2
Return
ElseIf ( button == 2 )
Set curryangle To ( curryangle + angle_increments )
If ( curryangle >= 360 )
Set curryangle To ( curryangle - 360 )
EndIf
SetAngle, y, curryangle
Set activate_menu To 2
Return
ElseIf ( button == 3 )
Set currzangle To ( currzangle + angle_increments )
If ( currzangle >= 360 )
Set currzangle To ( currzangle - 360 )
EndIf
SetAngle, z, currzangle
Set activate_menu To 2
Return
ElseIf ( button == 4 )
SetAngle, x, 0
SetAngle, y, 0
SetAngle, z, 0
Set activate_menu To 2
Return
ElseIf ( button == 5 )
SetAngle, x, startxangle
SetAngle, y, startyangle
SetAngle, z, startzangle
Set activate_menu To 2
Return
Else
Set activate_menu To 1
Set controlvar To 1
Return
EndIf
EndIf
;##################### Position Menu #######################
If ( activate_menu == 3 )
If ( increments == 1 )
MessageBox "Меню позиции", "Двигать на 1", "+X", "-X", "+Y", "-Y", "+Z", "-Z", "Восстановить", "Назад"
ElseIf ( increments == 5 )
MessageBox "Меню позиции", "Двигать на 5", "+X", "-X", "+Y", "-Y", "+Z", "-Z", "Восстановить", "Назад"
ElseIf ( increments == 10 )
MessageBox "Меню позиции", "Двигать на 10", "+X", "-X", "+Y", "-Y", "+Z", "-Z", "Восстановить", "Назад"
Else
MessageBox "Меню позиции", "Двигать на 30", "+X", "-X", "+Y", "-Y", "+Z", "-Z", "Восстановить", "Назад"
EndIf
Set activate_menu To 0
EndIf
If ( controlvar == 3 )
Set button To GetButtonPressed
If ( button == -1 )
Return
ElseIf ( button == 0 )
If ( increments == 1 )
Set increments To 5
ElseIf ( increments == 5 )
Set increments To 10
ElseIf ( increments == 10 )
Set increments To 30
Else
Set increments To 1
EndIf
Set activate_menu To 3
Return
ElseIf ( button == 1 )
Set currxpos To ( currxpos + increments )
SetPos, x, currxpos
Set activate_menu To 3
Return
ElseIf ( button == 2 )
Set currxpos To ( currxpos - increments )
SetPos, x, currxpos
Set activate_menu To 3
Return
ElseIf ( button == 3 )
Set currypos To ( currypos + increments )
SetPos, y, currypos
Set activate_menu To 3
Return
ElseIf ( button == 4 )
Set currypos To ( currypos - increments )
SetPos, y, currypos
Set activate_menu To 3
Return
ElseIf ( button == 5 )
Set currzpos To ( currzpos + increments )
SetPos, z, currzpos
Set activate_menu To 3
Return
ElseIf ( button == 6 )
Set currzpos To ( currzpos - increments )
SetPos, z, currzpos
Set activate_menu To 3
Return
ElseIf ( button == 7 )
SetPos, x, startxpos
SetPos, y, startypos
SetPos, z, startzpos
Set currxpos To startxpos
Set currypos To startypos
Set currzpos To startzpos
Set activate_menu To 3
Return
Else
Set activate_menu To 1
Set controlvar To 1
Return
EndIf
EndIf
;--------------------------------------------------------
;--------- Turning Realltime Rotation on or off ---------
;--------------------------------------------------------
If ( activate_menu == 5 )
If ( ReallTimeRotation == 0 )
Set ReallTimeRotation To 1
Else
Set ReallTimeRotation To 2
EndIf
Set activate_menu To 0
Set controlvar To 0
Set lockit To 1
EndIf
;----------------------------------------------------------------
;Scaling menu, allowing you To make the object bigger or smaller.
;----------------------------------------------------------------
If ( activate_menu == 4 )
If ( ScaleIncrements <= 0.06 )
MessageBox "Меню масштаба", "Масштабировать 0.05", "Большой", "Маленький", "Восстановить", "Масштаб"
ElseIf ( ScaleIncrements <= 0.15 )
MessageBox "Меню масштаба", "Масштабировать 0.1", "Большой", "Маленький", "Восстановить", "Назад"
Else
MessageBox "Меню масштаба", "Масштабировать 0.3", "Большой", "Маленький", "Восстановить", "Назад"
EndIf
Set activate_menu To 0
EndIf
If ( controlvar == 4 )
Set currscale To GetScale
Set button To GetButtonPressed
If ( button == -1 )
Return
ElseIf ( button == 0 )
;---------------------------------------------------------------
;ScaleIncrement is a float and a float is never an exact number
;wich a short or integer is. So therefor I do a check above the
;actuall value that I actually set. (Pekka)
;---------------------------------------------------------------
If ( ScaleIncrements <= 0.06 )
Set ScaleIncrements To 0.1
ElseIf ( ScaleIncrements <= 0.15 )
Set ScaleIncrements To 0.3
Else Set ScaleIncrements To 0.3
Set ScaleIncrements To 0.05
EndIf
Set activate_menu To 4
Return
ElseIf ( button == 1 )
Set currscale To ( currscale + ScaleIncrements )
;----------------------------------------------------------------
;I have to set a max and min limit or I think things might become
;nasty, specially if we try to make the object smaller then 0.
;I havnt test it and I will not test it either. I set max scale
;to 2x and min scale to 0.05x. Feel free to change it though. (pekka)
;---------------------------------------------------------------
If ( currscale >= 2.0 )
Set currscale To ( 2.0 )
MessageBox "Прошу прощения, сделать этот предмет больше не выйдет. Возьмите большой и я увеличу его."
EndIf
SetScale, currscale
Set activate_menu To 4
Return
ElseIf ( button == 2 )
Set currscale To ( currscale - ScaleIncrements )
If ( currscale <= 0.05 )
Set currscale To ( 0.05 )
MessageBox "Прошу прощения, сделать этот предмет еще меньше нельзя. Возьмите маленький и я сделаю его крошечным ."
EndIf
SetScale, currscale
Set activate_menu To 4
Return
ElseIf ( button == 3 )
SetScale, 1.0
Set activate_menu To 4
Return
Else
Set activate_menu To 1
Set controlvar To 1
Return
EndIf
EndIf
End
Этот скрипт позволяет вытворять все что угодно- только вот масштабирование глючит - возможно изза других скриптов? не знаю. Вы можете увидеть его действие в плагине Westly Happy Holyday, который есть у нас на сайте. Скрипт попроще для ковров можно найти в плагинах Faylinn.
Для задач посложнее читаем стр 66. учебника.
ДЗ: анимировать ворота и на базе скрипта Пекки хорошо подумав реализовать перемещение предмета по трем осям. (больше ничего пока не надо)