Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 08:02:31, Ed101 сказал(-а):Вот пример. Создаю новый объект-подсвечник. Вешаю скрипт на него, размещаю в ячейке. Активирую, и в консоли будет 0, а не 5. Задан неверный формат. Попробуй дебажить так: PrintToConsole "Значение - %g" a. Скорее всего, там все ок с назначением переменных, просто консоль не то значение выводится. Сам по себе блок OnLoad срабатывает отлично в случае, если ты через PlaceAtMe размещаешь объект или же сам объект, на котором висит скрипт, впервые загружается в ячейке. Важно, чтобы тебя в ней не было на момент его появления там. Данный блок не всегда работает так, как хочется. Как инициализатор, можно использовать условие-ограничитель типа: Short sLoad Begin GameMode if (sLoad == 0) Let sLoad := 5 Return Endif End Begin OnActivate PrintToConsole "Значение - %g" sLoad End Ничто не истинно, все потрачено
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 @Ed101, дружище, а мы с тобой по другому можем сделать) Раз нельзя отключить дочерний источник света без отключения родителя, его ведь всегда можно перенести за пределы ячейки с помощью SetPos и обновить его координаты через Update3D) А есть еще один вариант - с помощью OBSE-функций управлять самим источником света, в нужный момент загоняя радиус свечения в 0, что должно полностью его отключить. Но тут есть несколько проблем, одна из которых - отсутствие сохранения внесенных изменений в сейв игры, как и возврат в исходное. Это еще +геморрой и лишний код. Ничто не истинно, все потрачено
EdMSL Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 (изменено) 17.10.2021 08:41:47, Takirell сказал(-а): @Ed101, дружище, а мы с тобой по другому можем сделать) Раз нельзя отключить дочерний источник света без отключения родителя, его ведь всегда можно перенести за пределы ячейки с помощью SetPos и обновить его координаты через Update3D) А есть еще один вариант - с помощью OBSE-функций управлять самим источником света, в нужный момент загоняя радиус свечения в 0, что должно полностью его отключить. Но тут есть несколько проблем, одна из которых - отсутствие сохранения внесенных изменений в сейв игры, как и возврат в исходное. Это еще +геморрой и лишний код. Ты предлагаешь убирать его в -30000 по оси Z, например? Кстати да, с сейвами беда. Я не знаю всех данных, что хранятся в сейве. Enabled/Disabled точно есть. Изменено 17 октября, 2021 пользователем Ed101
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 08:47:13, Ed101 сказал(-а):Ты предлагаешь убирать его в -30000 по оси Z, например? Как вариант. И возвращать на исходные координаты, когда это необходимо. Проверить стоит, дело может выгореть) Ничто не истинно, все потрачено
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 08:49:12, Ed101 сказал(-а):Кстати да, с сейвами беда. Я не знаю всех данных, что хранятся в сейве. Enabled/Disabled точно есть. Практически все, что могут менять OBSE-функции (имена, пути к моделям\текстурам, какие-то параметры освещения\погоды\рас, шейдера и так далее) - все это не хранится в сейвах и требует возвращения значений на исходные. НО! Это не применимо к новым базовым объектам, созданных функцией CloneForm. Ну и CreateFullActorCopy. Иными словами, в редакторе и в плагинах нет объектов, созданных скриптом, они существуют только в сохранениях, как динамические объекты. Следовательно - игре просто неоткуда взять какие-то исходные параметры объекта из того же мастер-файла, т.к объекта в нем просто нет. Но тут стоит понимать, что если установлен плагин EngineBugFixes, то все объекты, созданные функцией CloneForm будут удалены в случае, если они не задействованы (не находятся в мире\контейнере\инвентаре игрока\или не используются в данный момент где-либо). Ничто не истинно, все потрачено
EdMSL Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 08:49:21, Takirell сказал(-а):Как вариант. И возвращать на исходные координаты, когда это необходимо. Проверить стоит, дело может выгореть) Ну что, работает твой вариант. Сразу видно опытного скриптера) Мне в Unity так изощраться не приходилось. ref current; ref children; begin onLoad set current to this; set children to current.GetNthChildRef 0; if (children.GetPos z <= -3000) current.RemoveFlames else current.AddFlames; endif children.Update3D; end begin OnActivate set current to this; set children to current.GetNthChildRef 0; if (children.GetPos z <= -3000) current.AddFlames; children.setPos z, -90; else current.RemoveFlames; children.setPos z, -30000; endif children.Update3D; end
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 09:36:44, Ed101 сказал(-а):Ну что, работает твой вариант. Хмм... скажи, а какую модель ты используешь в качестве подсвечника? Лучше EDID дай, я у себя тоже сделаю и чуть доработаю твой вариант скрипта. Ничто не истинно, все потрачено
EdMSL Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 (изменено) 17.10.2021 09:45:06, Takirell сказал(-а):а какую модель ты используешь в качестве подсвечника? middlecandlestickfloor04fake.nif Такую же модель, только со светом (не fake) использует CandlestickFloor04Orange512, например. Изменено 17 октября, 2021 пользователем Ed101
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 10:00:07, Ed101 сказал(-а):Chandelier04Fake.NIF Благодарочка, ща у себя намучу и скину свой вариант скрипта. Ничто не истинно, все потрачено
EdMSL Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 (изменено) 17.10.2021 10:00:53, Takirell сказал(-а):Благодарочка, ща у себя намучу и скину свой вариант скрипта. Перечитай сообщение, я исправил модель. Хотя это не принципиально, какая именно модель, главное чтобы была приписка fake. У них есть огни, но сами по себе они не излучают свет. Изменено 17 октября, 2021 пользователем Ed101
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 10:03:45, Ed101 сказал(-а): Перечитай сообщение, я исправил модель. Хотя это не принципиально, какая именно модель, главное чтобы была приписка fake. У них есть огни, но сами по себе они не излучают свет. Да я понял сразу, т.к источники света с моделью, которые сами по себе светятся. Ничто не истинно, все потрачено
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 @Ed101, Короче, наколдовал я такое универсальное дрыгало: scn TestCandleScript Short sLoad Float fDefPos Float fNewPos Ref rFlame Begin OnActivate if (sLoad > 0) if (sLoad == 1) rFlame.SetPos z fNewPos RemoveFlames Let sLoad := 2 Else rFlame.SetPos z fDefPos AddFlames Let sLoad := 1 Endif rFlame.Update3D Endif Return End Begin GameMode ;Инициализация if (sLoad == 0) if (IsFormValid rFlame == 0) Let rFlame := GetNthChildRef 0 Return Else Let fDefPos := rFlame.GetStartingPos z Let fNewPos := (fDefPos - 30000) Let sLoad := 1 Return Endif Endif ;Авто-фикс позиций и огней if ((GetGameLoaded || GetGameRestarted) && sLoad > 0) if (sLoad == 1) rFlame.SetPos z fDefPos if (HasFlames == 0) AddFlames Endif Elseif (sLoad == 2) rFlame.SetPos z fNewPos if (HasFlames > 0) RemoveFlames Endif Endif rFlame.Update3D Return Endif End Блок с авто-фиксом огней можно и убрать, в принципе, только вот если без него отключить огни и сразу же загрузится на сейв, где они включены - огней не будет. Приходится вручную перетыкивать) Убрал еще вообще блок OnLoad, т.к он не всегда выполняется корректно и тогда, когда это нужно. Ну и снес Ref-указатель на сам подсвечник, он банально не нужен и может вообще путать игру. 1 Ничто не истинно, все потрачено
EdMSL Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 10:51:46, Takirell сказал(-а):Ed101, Короче, наколдовал я такое универсальное дрыгало: Неплохо он так оброс. Но я, правда, надеялся, что обойдется без onGameMode, чтобы он постоянно не обрабатывался.
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 11:04:01, Ed101 сказал(-а): Неплохо он так оброс. Но я, правда, надеялся, что обойдется без onGameMode, чтобы он постоянно не обрабатывался. Можешь по аналогии переформатировать и без него, но тогда могут быть (и будут) косяки, о которых я писал выше. Просто эта чудесная игра не может нормально работать и вечно приходится костылить даже в, казалось бы, элементарных вещах. Это нормально написанный скрипт и игру грузить не будет, уж поверь. Игра больше будет лагать из-за источников света, чем от скриптов. 1 Ничто не истинно, все потрачено
EdMSL Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 (изменено) 17.10.2021 11:06:54, Takirell сказал(-а):Игра больше будет лагать из-за источников света, чем от скриптов. Тут да, согласен. Хорошо, теперь надо решить вторую проблему) В комнате есть общий выключатель. Сейчас в скрипте на каждый светильник и свет отдельная запись. Цель та же) Полагаю, надо задействовать массивы. Изменено 17 октября, 2021 пользователем Ed101
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 11:37:02, Ed101 сказал(-а):Полагаю, надо задействовать массивы. Зачем? Я чуть покумекаю и рожу готовый вариант, есть пара мыслей. 1 Ничто не истинно, все потрачено
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 Итого, что у меня получилося... Основной универсальный скрипт светильников был дополнен и чуть оптимизирован, теперь это чудовище выглядит вот так: scn TestCandleScript Short sLoad Short sValue Short sSwitch Float fDefPos Float fNewPos Ref rSwitch Ref rFlame Begin OnActivate if (sLoad > 0) if (IsActionRef rSwitch == 0) if (sLoad == 1) Let sLoad := 2 Else Let sLoad := 1 Endif Let sSwitch := 1 Else ;Т.к команда об активации была получена от основного рубильника, нам нужно понять - в каком именно положении он находится. Для этого считываем у него переменную sFlag Let sValue := rSwitch.GetVariable "sFlag" if (sValue == 0) && (sLoad != 2) Let sSwitch := 1 Let sLoad := 2 Elseif (sValue == 1) && (sLoad != 1) Let sSwitch := 1 Let sLoad := 1 Endif Endif Endif Return End Begin GameMode ;Инициализация if (sLoad == 0) if (IsFormValid rFlame == 0) Let rFlame := GetNthChildRef 0 Return Else Let fDefPos := rFlame.GetStartingPos z Let fNewPos := (fDefPos - 30000) Let sLoad := 1 Return Endif Else ;Инициализируем выключатель if (IsFormValid rSwitch == 0) Let rSwitch := GetParentRef Return Endif ;Блок, отвечающий за включение\выключение огня и света (объединенный) if (sSwitch > 0) if (sLoad == 1) rFlame.SetPos z fDefPos if (HasFlames == 0) AddFlames Endif Elseif (sLoad == 2) rFlame.SetPos z fNewPos if (HasFlames > 0) RemoveFlames Endif Endif rFlame.Update3D Let sSwitch := 0 Return Endif Endif ;Авто-фикс позиций и огней if ((GetGameLoaded || GetGameRestarted) && sLoad > 0) Let sSwitch := 1 Return Endif End А вот скрипт на выключателе (я использовал модельку рычага с EDID RFSwitchLever01): scn TestLightSwitchScript Short sCount Short sFlag Ref rChild Ref rMe Begin OnActivate if (IsAnimPlaying == 0) if (sFlag == 0) PlayGroup Forward, 1 Let sFlag := 1 Else PlayGroup Backward, 1 Let sFlag := 0 Endif ;Находим и активируем все дочерние светильники, привязанные к этому рычагу if (IsFormValid rMe == 0) Let rMe := GetSelf Endif Let sCount := GetNumChildRefs while (sCount >= 0) Let sCount -= 1 Let rChild := GetNthChildRef sCount ;На всякий случай пропускаем "битые" ссылки (если они есть) if (IsFormValid rChild == 0) || (IsRefDeleted rChild) continue Endif rChild.Activate rMe, 1 loop Return Endif End Собсна, чтобы все это работало, нужно разместить нужное кол-во светильников в помещении и каждый из них привязать через ParentRef к рычагу. Все остальное самостоятельно схватится и должно работать. Само собой, каждый светильник можно включать\выключать по желанию, вне зависимости от положения главного рубильника. P.S Есть еще парочка вариантов реализации задумки, но, как мне кажется, что приведенный выше метод - наиболее прост в исполнении. Ну, как по мне :D 2 Ничто не истинно, все потрачено
EdMSL Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 13:06:25, Takirell сказал(-а):P.S Есть еще парочка вариантов реализации задумки, но, как мне кажется, что приведенный выше метод - наиболее прост в исполнении. Ну, как по мне :D Сейчас затестим.
EdMSL Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 13:06:25, Takirell сказал(-а):P.S Есть еще парочка вариантов реализации задумки, но, как мне кажется, что приведенный выше метод - наиболее прост в исполнении. Ну, как по мне :D Не совсем идеально, но работает хорошо. Для моих целей более чем достаточно. Есть маленькая проблемка. Если включить или выключить вручную все светильники после того, как ты активировал общий рубильник, то общий рубильник срабатывает только со второго раза.
Takirell Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 17.10.2021 14:31:20, Ed101 сказал(-а): Не совсем идеально, но работает хорошо. Для моих целей более чем достаточно. Есть маленькая проблемка. Если включить или выключить вручную все светильники после того, как ты активировал общий рубильник, то общий рубильник срабатывает только со второго раза. Да, я знаю об этом. Просто нужно переменные авто-обновлять в зависимости от статуса всех светильников. Мб позже я подумаю, как это сделать. Ничто не истинно, все потрачено
EdMSL Опубликовано 17 октября, 2021 Опубликовано 17 октября, 2021 (изменено) Еще немного доработал скрипт. Но это, скорее, для моих нужд. Begin OnActivate if (IsActionRef Player // поставил проверку на запуск от игрока if (IsFormValid rMe == 0) Let rMe := GetSelf Endif Let sCount := GetNumChildRefs while (sCount > 0)// было >= 0, поэтому была лишняя проверка с индексом -1. Ошибка ловится, но зачем, когда можно избежать Let sCount -= 1 Let rChild := GetNthChildRef sCount if (IsFormValid rChild == 0) || (IsRefDeleted rChild) continue Endif rChild.Activate rMe, 1 loop ; Перенес в конец, т.к. изначально весь свет включен и рубильник срабатывал со второго раза. ; Убрал анимацию, просто не нужна. if (sFlag == 0) Let sFlag := 1 Else Let sFlag := 0 Endif Return Endif End Изменено 17 октября, 2021 пользователем Ed101 2
StasLeyke Опубликовано 23 октября, 2021 Опубликовано 23 октября, 2021 Как удалить ванильные ЛОДЫ? Деревья на территории Хаммерфелла летают и их нельзя удалить
Pimple03 Опубликовано 9 ноября, 2021 Опубликовано 9 ноября, 2021 Можно ли переориентировать по сторонам света ранее загруженную внутреннюю ячейку? К примеру я могу задать Reference для NorthMarker'а, а затем через скрипт и команду SerAngle Z изменить его положение. Но в результате изменится только отображение ячейки на миникарте, при этом маркеры дверей останутся на прежнем месте, а показания компаса и соответственно положение маркера игрока на карте никак не поменяются. Команда ResetInterior не помогает.
Bianor Опубликовано 9 ноября, 2021 Опубликовано 9 ноября, 2021 09.11.2021 07:38:16, Pimple03 сказал(-а):Можно ли переориентировать по сторонам света ранее загруженную внутреннюю ячейку? Так ведь в каждой ячейке есть компас-маркер.
Pimple03 Опубликовано 9 ноября, 2021 Опубликовано 9 ноября, 2021 09.11.2021 08:37:47, Bianor сказал(-а):Так ведь в каждой ячейке есть компас-маркер. Маркер то есть, но манипуляции с ним ничего кроме перечисленного выше не дают, если ячейка уже была однажды загружена.
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать аккаунт
Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти