Я так понимаю нужно еще доцепить условие проверки координат лифта, если он вверху, то надо ехать вниз, если уже стоит внизу, то ничего не делать. Я не знаю как akObject привязать к кнопкам вызова, знаю как через LinkedRef, но опять же не знаю, как указанную тобой команду akObject подправить под LinkedRef. Если не трудно, подскажи пожалуйста.
Scriptname LiftUp extends ObjectReference
Event OnActivate(ObjectReference akActionRef) if GetLinkedRef().Z == координата; лифт внизу (координату по оси Z взять из СК) GetLinkedRef().TranslateTo(GetLinkedRef().X,GetLinkedRef().Y,GetLinkedRef().Z + fZZ, 0.0, 0.0, 0.0, 200.0); отправка лифта вверх endif endEvent
Переменной fZZ надо или присвоить значение или заменить ее числом (координаты верхнего положения лифта должны быть известны). Нужны будут два скрипта - один для кнопок вверх, другой для кнопок вниз.
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №63
| Тема: Вопросы по скриптам Papyrus
написано: 16 декабря 2013, 20:54
| Отредактировано: LordVadim - 16 декабря 2013, 19:18
if GetLinkedRef().Z == координата ; лифт внизу (координату по оси Z взять из СК)
Добавлено (16 Декабря 2013, 23:06) --------------------------------------------- .
DarkVetal, Можно в СК поставить два XMarkerHeading в точки координат нижнего положения лифта и верхнего положения и вместо функции TranslateTo() использовать TranslateToRef().
Скрипт для кнопки вверх:
Scriptname LiftUp extends ObjectReference
ObjectReference Property xmUp Auto ; назначить в СК верхний XMarkerHeading
Ни каких проверок не нужно. Даже если в движущемся лифте нажать кнопку, то лифт или продолжит движение или начнет двигаться в обратном направлении в зависимости от кнопки. Кнопки через вкладку LinkedRef связать с лифтом. Если нужно отслеживать положение лифта при загрузке локации, то нужно будет добавить обработку событий: OnCellLoad() и OnTranslationComplete().
Добавлено (17 Декабря 2013, 00:54) --------------------------------------------- А лучше для кнопок использовать один скрипт:
Scriptname LiftUpDown extends ObjectReference
ObjectReference Property xmTarget Auto ; для кнопки вверх назначить в СК верхний XMarkerHeading, для кнопки вниз назначить в СК нижний XMarkerHeading
Но это скрипт Алекса, который не компилируется, а я говорю о твоем (от маркера к маркеру, при первом запуске платформа поворачивается по часовой стрелке где-то на 3\4)
Значит надо тот маркер, к которому едет платформа повернуть в противоположную сторону на 3/4. Проверь в СК углы поворота маркеров должны совпадать с углами поворота лифта.
Для точного позиционирования в СК порядок действий такой: Отодвинь маркеры в сторону, что бы не мешали. Поставь лифт в верхнее положение и открой свойства 3D Data. Открой свойства 3D Data для верхнего маркера. Все значения Position и Rotation из свойств лифта скопируй в свойства маркера. Тоже самое для нижнего положения лифта и нижнего маркера. Теперь лифт будет двигаться точно между заданными координатами не поворачиваясь.
Добавлено (18 Декабря 2013, 10:42) --------------------------------------------- На счет подвисающего ГГ - попроси помощи у Алекса. Он как то упоминал функцию SetVehicle() - привязки к объектам, я с ней не разбирался, а Алекс наверняка знает как она работает.
Подскажите скрипт, который можно повесить на активатор для выключения/включения музыкального сопровождения в заданной локации. С условиями вроде: если музыка включена - отключить, если музыка отключена - включить. Сам пробовал решить этот вопрос окольными путями. Добавил за пределы локации объект MyStatic и в музыкальных треках добавил условие GetDisabled MyStatic == 0, а к активатору прикрутил скрипт: ... Ничего хорошего не получилось. Музыка выключается, но обратно ее вернуть не выходит.
SoundCategory Property AudioCategoryMUS Auto;- Категория для отключения фоновой музыки игры
BoolPropertyMyMute = False Auto Hidden
Function SetMute() IfMyMute AudioCategoryMUS.Mute();- Отключаем фоновую музыку Else AudioCategoryMUS.UnMute();- Включаем фоновую музыку EndIf EndFunction
Со скриптами у меня пока всё плохо, однако хочу реализовать одну идею. В общей картине нужно чтобы в определённом месте появлялся объект на несколько секунд и затем исчезал. Может кто подскажет как это сделать?
при активации рычага или же попадание в определённое место на карте, скажем ходьба через коридор где игрок наступает на триггер и появляется нужный объект. Например чтобы пройдя коридор за спиной появился, предположим, скелет.
Вы даете кучу разных условий, алгоритмы реализации которых могут сильно различаться. Сомневаюсь, что в этой ветке кто то будет писать целую лекцию по скриптингу и использованию СК. Здесь (по возможности) помогают решать конкретные проблемы. Поэтому, если вы нуждаетесь в помощи, точно сформулируйте проблему, которую хотите решить.
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №72
| Тема: Вопросы по скриптам Papyrus
написано: 22 января 2014, 17:29
| Отредактировано: LordVadim - 22 января 2014, 17:30
да тут даже не проблема а скорее полное незнание скриптинга. Согласен что никто здесь лекцию писать не будет, так что лучше я закрою свой вопрос. Пойду штурмовать всевозможные вики. Но всё равно спасибо.
Будут конкретные вопросы обращайтесь. Кстати, в этой ветке ранее обсуждался вопрос по отображению/скрытию предметов при активации рычага, поищите - может пригодится.
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №73
| Тема: Вопросы по скриптам Papyrus
написано: 24 января 2014, 19:46
| Отредактировано: LordVadim - 24 января 2014, 19:57
AleksTirex, разве с xMarkerHeading нужно использовать не PlaceAtMe()? И зачем удалять созданного актера через 5 секунд после создания? Он же для чего то создавался...
И попутно вопрос: вот таким образом созданный, а потом удаленный актер оставляет какие либо следы в сейвах или нет?
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №74
| Тема: Вопросы по скриптам Papyrus
написано: 25 января 2014, 04:44
| Отредактировано: LordVadim - 25 января 2014, 04:45
Но теперь другая проблема, как сделать чтобы при заходе на триггер нпс создавался единожды а то получаются сплошные дубликаты.
Вот об этом я и писал - нужно точно определиться, что ты хочешь сделать... Если нужно, что бы НПС был создан один раз, зачем заморочки со сложными скриптами? В СК создаешь в нужном месте НПС скрытым по умолчанию (отмечено Initially Disabled). Триггер или активатор связываешь с НПС через Linked Ref. На триггер или активатор вешаешь скрипт:
Event OnActivate(ObjectReference akActionRef) ;- Произошло событие - активирован активатор if akActionRef == Game.GetPlayer();- Если событие вызвано игроком Self.GetLinkedRef().Enable();- Связанного с активатором НПС делаем видимым endif endEvent
Event OnTriggerEnter(ObjectReference akActionRef);- Произошло событие - вход в зону триггера if akActionRef == Game.GetPlayer();- Если в зону триггера вошел игрок Self.GetLinkedRef().Enable();- Связанного с триггером НПС делаем видимым endif endEvent
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №76
| Тема: Вопросы по скриптам Papyrus
написано: 30 января 2014, 19:55
| Отредактировано: LordVadim - 30 января 2014, 19:58
подскажите, можно ли как то скриптами заставить непися (например корову или курицу) остановиться и не двигаться некоторое время, секунд на 10 ? что то вроде дизэйблАИ, только что бы совсем отрубалось ее АИ и главное ноги, а не только способность замечать ГГ
Можно. На НПС вешается скрипт:
Scriptname StopAIActorScript extends Actor
Event OnActivate(ObjectReference akActionRef);- Событие активации НПС if akActionRef == Game.GetPlayer();- Если активировал игрок Self.EnableAI(False) ;- Отключаем AI Debug.Wait(10);- Ждем 10 секунд Self.EnableAI(True) ;- Включаем AI endif endEvent
Но при этом нельзя трогать скрипт на тригаре. Поэтому у меня была мысль на обьект повесить еще один скрипт с проверкой, но я не знаю, при помощи чего запустить event.
А не проще было бы на триггер повесить еще один скрипт в котором и делать проверки?
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №79
| Тема: Вопросы по скриптам Papyrus
написано: 7 февраля 2014, 11:59
| Отредактировано: LordVadim - 7 февраля 2014, 12:00
Но самое было б замечательное старт евента при появлении обьекта, но такой функции в скриптах нет!
Правильным решением было бы все таки изменить скрипт на триггере. Если этого не делать, то единственным решением, на мой взгляд, будет следующее:
Scriptname VerificationSCRIPT extends ObjectReference ;- Дополнительный скрипт на триггере
Event OnActivate(ObjectReference TriggerRef) ;- Событие активации триггера RegisterForUpdate(0.1) ;- Включаем вызов процедуры OnUpdate() 10 раз в секунду Utility.Wait(10) ;- Задержка (время задержки установить чуть больше чем необходимо для срабатывания основного скрипта триггера) UnregisterForUpdate() ;- Отключаем вызов процедуры OnUpdate() EndEvent
Event OnUpdate() ;- Событие вызывается 10 раз в секунду ;- ;- Здесь проводить необходимые проверки объектов (функции IsDisabled()IsEnabled() ) ;- EndEvent
А зачем вы использовали евент он апдейт?! Не проще ли будет event onTriggerLeave потом utility.wait а дальше оператор ветвления на проверку?
Ты же сам сказал, что не можешь точно рассчитать время которое нужно поставить в Wait(). Если поставить слишком короткую задержку - проверки могут пройти до окончания работы основного скрипта. Если слишком длинную - объекты будут "моргать" на экране, то есть появляться на какое то время, а затем исчезать. А через OnUpdate() состояние объектов проверяется 10 раз в секунду (можно и чаще). То есть как только состояние изменилось выполняются твои проверки и объект или скрывается или остается видимым. Пользователь, практически, не заметит появления ("моргания") объекта на экране если он должен быть скрыт.
Это код из модификации Lightning Just in Time. Он очень хитрий и я решил не трогать его а добавить свой скрипт.
Ничего особо хитрого я тут не увидел. Все изменения видимости объектов происходят в событии OnUpdate(). Тебе, всего лишь, в конец этого события (перед EndEvent) надо вставить свои проверки и изменять видимость объектов как тебе нужно... и всё.
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №82
| Тема: Вопросы по скриптам Papyrus
написано: 23 февраля 2014, 06:22
| Отредактировано: LordVadim - 23 февраля 2014, 06:31
Вешаю на триггер DefaultPlaySoundAtLinkSCRIPT и в нужном месте воспроизводится нужный звук, но повесив его на активатор, тот же рычаг, ничего не происходит. Может другой скрипт нужен?
Сделай из DefaultPlaySoundAtLinkSCRIPT новый скрипт, заменив onTriggerEnter(ObjectReference triggerRef) на OnActivate(ObjectReference triggerRef) и все будет работать. Да, если активатором планируешь пользоваться несколько раз, надо из скрипта убрать self.disable().
Event OnUpdate() iTime +=1 if iTime == 1 ;- выполняются действия 1 события ElseIf iTime == 3 ;- выполняются действия 2 события ElseIf iTime == 5 ;- выполняются действия 3 события ElseIf iTime == 10 ;- выполняются действия 4 события UnRegisterForUpdate() EndIf EndEvent
Добавь в СК на месте панелей плоскости коллизии. В скрипты добавь ссылку на плоскость ObjectReference Property prCollision Auto При поднятии панели у соответствующей плоскости делай prCollision.Disable(), при опускании prCollision.Enable().
ObjectReference Property prCollision Auto - это в скрипт панели вставить? В какую лучше строку скрипта вставить, чтоб не поломать скрипт? И потом как назначить нужную панель, через Properties или LinkedRef? prCollision.Disable() prCollision.Enable() - это в скрипт ручек добавить надо, в какую лучше строку скрипта вставить, чтоб не поломать скрипт? И потом как назначить нужную панель, через Properties или LinkedRef? Я нуб в скриптах, поэтому и уточняю
У тебя панели поднимаются двумя кнопками. На каждой скрипт, я правильно понимаю? Если так, то в каждый скрипт, в начале, в разделе объявления свойств, вставляешь: ObjectReference Property prCollision Auto И в СК значению prCollision присваиваешь ссылку на плоскость коллизии (в обоих скриптах на одну и туже плоскость). В скрипт кнопки "опустить", после TranslateToRef вставляешь: prCollision.Enable() В скрипт кнопки "поднять", после TranslateToRef вставляешь: prCollision.Disable() Если сам не разберешься - скинь скрипты я посмотрю.
А вот тут я его включаю и выключаю, от чего он, конечно, одевается но его нехило так мограет по локации тудыма сюдыма.
Есть три пути решения: 1) Использовать расширение SKSE для того, чтобы одеть персонажа не используя Disable/Enable. (Некоторые игроки не используют SKSE) 2) Скрывать персонажа на время операции Disable/Enable и возвращать его потом на место. (НПС моргнет, но мотать по локации его не будет) 3) Если скриптом раздеваются обычные НПС, то можно их одевать назначая Outfit. (самый простой вариант, но срабатывать будет только на НПС имеющих Outfit)
Какой вариант будем реализовывать?
Изменение репутации для пользователя LordVadim
LordVadimOffline
Сообщение №89
| Тема: Вопросы по скриптам Papyrus
написано: 21 марта 2014, 08:13
| Отредактировано: LordVadim - 21 марта 2014, 08:14
В общем любой из первых двух на ваш выбор, какой удобней и проще вам.
Попробуй сначала всё же через Outfit:
Event OnTriggerLeave (ObjectReference akActionRef) Actor akActor = akActionRef as Actor If (akActor != Game.GetPlayer()) Utility.Wait(5) akActor.SetOutfit(akActor.GetActorBase().GetOutfit()) EndIf EndEvent
Если не будет срабатывать, тогда так:
Event OnTriggerLeave (ObjectReference akActionRef) Actor akActor = akActionRef as Actor If (akActor != Game.GetPlayer()) Utility.Wait(5) Form akItem Int akCount = akActor.GetNumItems();- Количество вещей в инвентаре While akCount > 0 akCount -= 1 akItem = akActor.GetNthForm(akCount);- Берём вещь под номером akCount if akItem.GetType() == 26;- Если это "Armor" akActor.EquipItem(akItem);- Одеваем вещь EndIf EndWhile EndIf EndEvent
Значит у тебя не установлены скрипты SKSE. Из архива SKSE взять все содержимое папки SKSE\Data\Scripts и скопировать с заменой в папку Skyrim\Data\Scripts