Пятница, 26.04.2024, 16:19
Under sky of Half-Life
Приветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
Меню сайта

Категории каталога
На движке Valve Source [29]
На движке Half-Life 1 [1]

Главная » Статьи » Статьи по мэппингу » На движке Valve Source

Работа с VScripts. Part 1

Учебник по использованию vscripts. Необходимо знание логики Source и базовое знание языка С или С++.

Работает на L4d2, Portal 2, CS:GO, ASW и др. последних.

Возможности:

*Математические расчеты расстояния, направления, движения объектов.

*Запись и хранение большого количества данных.

*Манипуляциии с энтитями: перемещение, вращение, смена модели и т. д.

*И все др. что не может быть сделано маппингом.

*Возможность фиксить баги логики и энтитей карты после релиза

*Безопасное обновление рекомпиленных карт (чтоб автосейв у игроков не ломался)

*Быстрая, мощная и стабильная скриптовая платформа выдерживающая большое количество кода и переменных без лагов.

Плюсы и минусы:

Плюсы:

*Простая настройка и использование.

*Очень простой язык программирования (Sqirrel).

*Не требует компиляции. Двиг сам скомпилит скрипт при запуске карты.

*Возможность поцепить скрипты почти на любые энтити (имеющие поддержку скрипта). Скрипты выполняются независимо друг от друга.

 

Минусы:

*Узко направленность. Работает только с функциями описанными в документации и функциями языка Sqirrel.

*Любая ошибка останавливает подальшее выполнение скрипта.

*Сохранение/загрузка не корректно сохраняет массивы с огромным кол-вом данных

*Некоторые описанные функции в документации не работают (чтение/запись keys/values энтитей).

Необходимое ПО:

Notepad++ (рекомендую) или другой текстовый редактор с подсветкой синтаксиса языка С.

Настройка Хаммера

В настройках Хаммера -Game configuration-Game data files -> Add. В окне base.fgd - правой кнопкой - открыть, найти logic_script и добавить после Group15 строку:

 

input CallScriptFunction(String) : "CallScriptFunction"

 

Мы теперь в Хаммере будет виден инпут CallScriptFunction, который вальвам было просто впадлу вписать.

Пример работы

Для примера мы будем двигать объект в указанном направлении с указанной скоростью и выдавать на экран расстояние от игрока до объекта.

 

Ставим на карту энтитю logic_script

Имя: vscript

Script Think Function: function_update (функция, которая вызывается 10 раз в секунду). Имя функции на свое усмотрение.

 

 

Создаем в папке мода\scripts\vscripts файл TestScript.nut. Расширение файла сразу можно асоциировать с Notepad++.

Указываем этот файл в энтите в параметре Entity scripts. Manage- Плюсик

 

 

Создаем func_brush. Solidity: Never Solid (чтоб игрок в нем не застревал). Его мы будем двигать к игроку

 

 

Указываем этот объект в логик скрипте в параметре EntityGroup[0]. В этих параметрах можно указывать энтити для более быстрого доступа к ним в скрипте.

 

 

Открываем наш TestScript.nut в Notepad++, жмем в программме Синтаксисы - С - С.

Создаем нашу функцию обновления (указанную в энтите) и пишем движения куба:

 

Offset<-0 //переменная которая будет хранить смещение объекта

function function_update()

{

   SendToConsole("developer 1")  //Устанавливаем чтоб видеть на экране дебаг сообщения функции print.

 

   EntityGroup[0].SetAbsOrigin(Vector(Offset, EntityGroup[0].GetOrigin().y, EntityGroup[0].GetOrigin().z))  //Смещаем объект по оси X (с переменной Offset), остальные координаты Y и Z берем с объекта

print(Distance(EntityGroup[0],Entities.FindByName(null, "!player"))+"\n") //Выводим на экран дистанцию к игроку

 

   Offset+=0.2  //Увеличиваем переменную смещения. Каждую секунду куб будет смещаться на 0.2 * 10 раз в секунду = 2 юнита.

}    

 

function Distance(target1,target2) //Функция которая возвращает дистанцию между энтитями target1 - target2

{

    if(target1!=null && target2!=null)

    {

        DistanceToTarget<-0

        x1<-target1.GetOrigin().x

        y1<-target1.GetOrigin().y

        z1<-target1.GetOrigin().z

        

        x2<-target2.GetOrigin().x

        y2<-target2.GetOrigin().y

        z2<-target2.GetOrigin().z

 

        if(x1-x2>0) //Эту хрень приходится делать ибо нельзя взять корень с отъемного числа

        x12<-x1-x2

        else

        x12<-x2-x1

        if(y1-y2>0)

        y12<-y1-y2

        else

        y12<-y2-y1

        if(z1-z2>0)

        z12<-z1-z2

        else

        z12<-z2-z1

        DistanceToTarget=sqrt((x12)*2+(y12)*2+(z12)*2)

        return DistanceToTarget

    }

}

Куб движется, на экран выводится дистанция от куба к игроку:

Запуск указанной функции.

Для запуска конкретной функции в скрипте используем инпут на logic_script:

ИмяЛогикСкрипта-CallScriptFunction : ИмяФункции

Например мы хотим сбросить чтоб куб начал двигаться заново с 0-й позиции. Нужно сбросить переменную Offset:

function Reset()

{

Offset=0

}

 Ставим кнопку и пишем аутпут:

OnPressed-ИмяЛогикСкрипта-CallScriptFunction : Reset

 

Одноразовый запуск кода

 

Используется для инициалипзации.

 

Init<-0

function function_update()

{

if(!Init)

{

(..код одноразового запуска..)

 

Init=1

}

}

Скорость выполнения кода.

Если использовать указанную think функцию в энтите, то движок будет запускать указанную функцию в коде 10 раз в секунду.

Есть способ увеличить скорость выполнения кода до 30 раз в секунду. Это предел. (А больше и не нужно. Даже если нужно записывать движение какого-то объекта а потом восстанавливать его движение по той же траектории то такой скорости вполне достаточно. Есть сглаживание, но об этом позже.)

Для увеличения скорости выполнения update функции используем logic_relay и аутпуты

 

OnTrigger-ИмяЛогикСкрипта-CallScriptFunction : ИмяФункции

OnTrigger-!self-Trigger задержка 0,03

OnSpawn-!self-Trigger

Во фллагах реле установить Allow Fast Retrigger

 

Если использовать think функцию и по ходу выполнения возникнет ошибка, то код полностью остановится до перезапуска карты. Если использовать внешний источник запуска функции, то код будет выполнятся от начала функции до ошибки.

Отладка кода.

Основная функция которая используется для дебага это print("My message") которая выводит указанное сообщение в консоль и левый верхний угол экрана. Кроме текста в ней обычно выводится значение переменных. Пример:

 

counter<-0

function update()

{

print("My counter value: "+ counter++ +"\n")

}

"\n"- это перенос строки. Каждый новый print() будет писатся с новой строки, а не друг за другом.

 

Изменение типа данных.

Допустим у нас есть 2 переменные: Х и Y. Их значения 35 и 65. Нам нужно вывести их в дебаг слитно- 3565.

Если мы напишем

print(X+Y)

То в дебаге мы получим число 100. Для исправления пишем:

print(X.tostring+Y.tostring)

Таким способом мы переводим переменную int в строковую и соеденяем их.

Другой вариант для этого случая:

print(X+""+Y)

При этом X и Y разделяются пустой строкой и автоматически переводятся в string.

Остальные функции можно найти тут: http://www.squirrel-lang.org/doc/squirrel2.html

Часть 2

Категория: На движке Valve Source | Добавил: stridemann (05.08.2014) | Автор: Stridemann
Просмотров: 3642 | Комментарии: 1
Всего комментариев: 1
1 JOHN  
Небольшой баг-репорт:

Цитата
Возможность поцепить скрипты
*Узко направленность
Любая ошибка останавливает подальшее
нельзя взять корень с отъемного числа

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа
Логин:
Пароль:

Поиск

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

© 2024, MonoLife