ruggaraxe ruggaraxe

Jusper, Спасибо! По железу средней требовательности. Достаточно Intel Core i5 и 16 Гб ОЗУ и карту типа Geforce 1050. Это так, навскидку. Детально пока не замеряли.

Jusper Jusper

Девблог интересный. Статичный скриншоты очень доставляют.
Сильно игрушка сейчас требовательна к железу?

alexprey alexprey

Скриншоты великолепны!)

yo_serjio yo_serjio

alexprey, редактор зданий да) с возможностью шейрить прессеты другим людям)
На данном этапе можно только пристрои делать, поддержка полной смены архитектуры в будущем планируется)

Mariya Mariya

Всем привет!
Новый ролик на движке. Сегодня мы покажем Вам бытовые сцены из жизни Сырны, и то как мы расставили мебель в ее домике.

RedHelium RedHelium

Работаю над освещением и над игровым контроллером, скоро приступлю к разработке прототипа города. Пока некоторые наброски..

alexprey alexprey

О это что то вроде редактора зданий? Можно самостоятельно новые дома собирать?

yo_serjio yo_serjio

Jusper, yo_serjio, через воркшоп будет потом работать?
Пока что, работает перебросом текстового файла с городом, в теории должно и сообщением передаваться.

Jusper Jusper

yo_serjio, через воркшоп будет потом работать?
Пока что, работает перебросом текстового файла с городом, в теории должно и сообщением передаваться.

yo_serjio yo_serjio

Jusper, подстроить дизайн домов под себя, если не нравится стандартный) можно же будет летать в чужие города, персонализайия в этом плане сыграет только на руку)

Jusper Jusper

Вернул тебе ссылку на ич, невалидная была.
Выглядит оч круто. Надо пощупать. А в чем смысл такого редактора в игре? Что можно будет делать?

Tartal Tartal

Попробовал воплотить злодея-пришельца (раса до сих пор без названия) для Exterminator'а в 3D, скетч которого я недавно показывал здесь:

EfReeZe EfReeZe

SINILIAN, привет, мультфильм "Планета сокровищ". Рекомендую :)

Mariya Mariya

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

Wings' might Wings' might

Всем привет друзья, на этой неделе я добавил отображение урона, критические удары; обновил интерфейс магазина и изменил меню способностей

Следить за ежедневными изменениями: https://vk.com/wingsmight

Razz Razz

Сбегаем от контролёра
https://vk.com/iron_meat_game

SINILIAN SINILIAN

С приветом)) Что за мульт или фильмец?
(последний трек если что)

Mariya Mariya

Всем привет!
В мире Сырны появилось второе живое существо - лягушка!

Wings' might Wings' might

Всем привет, друзья)
На этой неделе добавил достижения, статистику и дополнительную информацию в виде отдельных панелек. (можно увидеть на гифке)

Логотип проекта Unreal Engine

Перегрузка функций

Перегрузка функций

Так же, как и в случае с переменными, функции родительских классов также переходят новым скриптам. И, так же, как и переменные, эти функции в новых классах можно менять. Для примера, заглянем в Inventory\UTInventory\UTTimedPowerup. Там мы найдем два усилителя из UT3 - UTBerserk и UTUDamage. Каждый из них наследует от Inventory функцию GivenTo. Несмотря на то, что в обоих классах название функции одинаковое, в UTBerserk она влияет на скорость стрельбы подобравшего бонус игрока, а в UTUDamage увеличивает наносимый оружием урон. Также у каждого класса свое звуковое сопровождение для этой функции. В этом и заключается перегрузка функций - изменение или дополнение действия, которое совершает функция.

Для демонстрации, как же перегрузка функций может повлиять на игру, мы создадим собственные PlayerController и GameInfo

Создание собственных GameInfo и PlayerController

GameInfo определяет правила игры. Примерами разных GameInfo являются Deathmatch и Capture The Flag. Это один из наиболее важных файлов в новой игре, и, чаще всего, именно он создается первым.

PlayerController - "мозг" нашего персонажа в игре. Именно он принимает сигналы, которые мы подаем через клавиатуру и мышку, он управляет нашим взглядом (сиречь, камерой), обменивается информацией с другими игроками, и много чего другого важного.

Создать начальную заготовку для GameInfo не так уж и сложно. Создайте новый класс с названием TestGame.uc

class TestGame extends UTDeathmatch;

defaultproperties
{
}

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

Теперь PlayerController. Создайте скрипт под названием TestPlayerController.uc и наберите там следующий код.

class TestPlayerController extends UTPlayerController;

simulated function PostBeginPlay()
{
     super.PostBeginPlay();
     `log("TestPlayerController spawned!");
}

defaultproperties
{
}

Помимо простой заготовки для контроллера, мы также добавили отладочный код, чтобы проверить, действительно ли создался нужный нам PC //(буду сокращать, так как очень долго пишется).

Одной из обязанностей GameInfo является определение, какой же PC будет спавниться. Для того, чтобы сказать игре, чтобы она создавала именно наш контроллер, добавьте в defaultproperties в нашем TestGame.uc следующую строчку

PlayerControllerClass=class'TestGame.TestPlayerController'

Первая часть в кавычках после class является названием папки, где находятся наши скрипты. PlayerControllerClass - переменная, которая объявлена в GameInfo, и наследуется всеми его подклассами, включая TestGame.

Скомпилируйте код.

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

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

<путь к корневой папке UDK>\Binaries\Win32\UDK.exe USTutorialMap?GoalScore=0?TimeLimit=0?Game=TestGame.TestGame  -log

Эта строчка говорит нам запустить файл UDK.exe, загрузив сразу определенную карту (в нашем случае, USTutorialMap, которую я предоставил в первой подстатье), без лимита времени и очков (для игрового режима Deathmatch), и используя тип игры TestGame, который находится в папке TestGame. А -log обозначает, что мы хотим параллельно запустить окошко лога, которое будет изменяться в реальном времени (иногда бывает полезно туда заглядывать).

Напоследок переименуйте файл в, например, Test Game.bat. Само название значения не имеет, главное, чтобы расширение было bat. Теперь этот файл будет запускать нашу пробную игру.

Запустите игру, после чего проверьте лог. Там вы должны обнаружить

[0005.67] ScriptLog: TestPlayerController spawned!

Теперь мы знаем, что создается именно наш контроллер. Но что с ним делать дальше?

Изменение камеры с помощью TestPlayerController

Мы можем использовать функции PC, чтобы менять положение и направление нашей камеры. Давайте сделаем камеру с видом сверху, чтобы превратить нашу игру в эдакое подобие Crimsonland или Gauntlet.

За положение камеры отвечает функция GetPlayerViewPoint, которую мы и перегрузим.

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

Перегрузка функций — Unreal Engine — DevTribe: Разработка игр

Мы могли бы просто добавить определенную величину в функции, но создать соответствующий вектор будет куда лучше, так как код будет более организованным. Внесите следующие изменения в наш PC

class TestPlayerController extends UTPlayerController;

var vector PlayerViewOffset;

defaultproperties
{
    PlayerViewOffset=(X=-64,Y=0,Z=1024)
}

Смещение по Z поднимет камеру вверх, а по X - сдвинет немного вперед. Числа можно менять по своему вкусу, но мне пока подходят и такие. Если хотите можете сдвинуть даже по Y.

Теперь сама функция. Объявлена она в Controller.uc, там мы и видим, как же она должна быть записана. //Забыл сказать, при перегрузке функции мы обязательно должны объявлять ее абсолютно также, как она была объявлена изначально.

simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)

Добавим ее в код нашего контроллера

simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)
{
}

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

simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)
{
     super.GetPlayerViewPoint(out_Location, out_Rotation);
}

Пока мы ничего не изменили. После компиляции и запуска это будет обычный шутер от первого лица. Для изменений нужно непосредственно применить наш сдвиг. Добавьте следующий код после супера

if(Pawn != none)
{
    out_Location = Pawn.Location + PlayerViewOffset;
    out_Rotation = rotator(Pawn.Location - out_Location);
}

Теперь объясняю по шагам.
Для начала мы проверяем, есть ли у нашего контроллера павн. Павн - это физическое воплощение нашего персонажа - его модель, здоровье, показатели, именно он вместо нас двигается, стреляет и т.д.. Контроллер - просто "интеллектуальная" часть персонажа, он даже не двигается. И для того, чтобы следовать за персонажем, мы должны смещать камеру именно относительно павна. Именно этому посвящена первая строчка после if - мы задаем положение камере, просто сдвинувшись от положения павна.

Вторая строчка посложнее. Нам нужно, чтобы камера всегда смотрела на павна. Для этого мы вычитаем положение камеры с положения павна, получая вектор, направленный от камеры до павна, и превращаем его в ротатор. Чтобы было лучше понятно, объяснение в картинках. Припустим, нам необходимо найти вектор С, имея вектор А и вектор В.

Перегрузка функций — Unreal Engine — DevTribe: Разработка игр

Чтобы получить С, мы можем просто развернуть А, и добавить к получившемуся -А вектор В

Перегрузка функций — Unreal Engine — DevTribe: Разработка игр

В итоге, мы получим С=-А+В, или можно переписать как С=В-А. В нашем случае, В - это положение павна, а А - положение камеры.

Скомпилируйте код и запустите игру.

Перегрузка функций — Unreal Engine — DevTribe: Разработка игр

"Что за нафиг?!" спросите вы. Мы стреляем только в землю, да и самого игрока не видно, только огромная пушка. Привыкайте, процентов в 80 всех случаев в программировании ваша программа не будет работать правильно сразу. Все программирование основано на принципе "пусть после того, как я решу эту проблему, возникнет новая, но я все равно ближе к тому, что задумал вначале". Главное - уметь исправлять текущие проблемы. А главный шаг к этому - знание, почему случилось именно так, а не иначе. Начнем с невидимого павна.

Дело в том, что по умолчанию модель павна скрыта для взгляда самого игрока. Если вы спросите "а почему же я вижу руки персонажа и оружие?", ответ предельно прост - это отдельные модели, которые видите только вы. Руки существуют только до локтей. Дело в том, что по умолчанию вы смотрите как бы из головы павна. И если бы павн не был невидимым, вы бы видели не пространство впереди, а кучу полигонов, которыми является поверхность головы павна изнутри. Именно поэтому его прячут.

Но ведь нам это не грозит. Поэтому это можно изменить. Решается это следующим образом. Добавьте в функцию строчку Pawn.Mesh.SetOwnerNoSee(false);, чтобы она выглядела так

simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)
{
     super.GetPlayerViewPoint(out_Location, out_Rotation);

     if(Pawn != none)
     {
          Pawn.Mesh.SetOwnerNoSee(false);

          out_Location = Pawn.Location + PlayerViewOffset;
          out_Rotation = rotator(Pawn.Location - out_Location);
     }
}

Скомпилируйте и запустите.

Перегрузка функций — Unreal Engine — DevTribe: Разработка игр

Уже лучше? Немного мозолит глаза прицел, но нам пока не до него, у нас проблемы посерьезней. Если бы на нас напали, мы бы ничего не смогли сделать, так как стреляем в землю. Этим и займемся.

По умолчанию, в обычном шутере от первого лица, когда стреляет оружие, игра спрашивает у контроллера, куда направлять снаряд. Обычно контроллер приказывает направлять его по направлению камеры. Но нам это абсолютно не подходит, так как смотрит наша камера в землю под павном. Для решения проблемы существует функция GetAdjustedAimFor, которая изменяет направление стрельбы. Добавьте следующий код после нашей GetPlayerViewPoint

function Rotator GetAdjustedAimFor( Weapon W, vector StartFireLoc)
{
     return Pawn.Rotation;
}

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

class TestPlayerController extends UTPlayerController;

var vector PlayerViewOffset;

simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)
{
    if(Pawn != none)
    {
        Pawn.Mesh.SetOwnerNoSee(false);

        out_Location = Pawn.Location + PlayerViewOffset;
        out_Rotation = rotator(Pawn.Location - out_Location);
    }
}

function Rotator GetAdjustedAimFor( Weapon W, vector StartFireLoc)
{
     return Pawn.Rotation;
}

defaultproperties
{
     PlayerViewOffset=(X=-64,Y=0,Z=1024)
}

Скомпилируйте и проверьте игру.

Перегрузка функций — Unreal Engine — DevTribe: Разработка игр

Еще лучше. Теперь можно взяться и за прицел.

Удалить прицел мы можем тремя способами. Первый - за это отвечает конфигурационная переменная в контроллере, и мы можем поменять ее по умолчанию, в соответственном INI файле, но в таком случае, игрок сможет вернуть ее в обратное состояние. Второй - мы можем удалить прицел из соответственного файла ScaleForm, но ScaleForm я в этой статье затрагивать не буду. Третий способ наиболее надежный - отключать прицел в начале каждой игры. Сделать это можно с помощью уже знакомой вам функции PostBeginPlay(). Добавьте ее перед самой первой функцией в контроллере:

simulated function PostBeginPlay()
{
    super.PostBeginPlay();
    bNoCrosshair = true;
}

Мы вызвали супер (наиболее важный шаг в перегрузке функций), после чего поменяли соответственную переменную. Скомпилируйте и проверьте.

Перегрузка функций — Unreal Engine — DevTribe: Разработка игр

Почти закончили. Осталась только гигантская пушка.

Помните, я говорил про вид от первого лица? Висящее в воздухе оружие как раз является моделью, которую мы видим от первого лица. Ее тоже можно спокойно отключить. Добавьте следующий код в блок if нашей функции GetPlayerViewPoint

if(Pawn.Weapon != none)
    Pawn.Weapon.SetHidden(true);

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

Перегрузка функций — Unreal Engine — DevTribe: Разработка игр

Успех, товарищи!

Если для кого-то успеха нет, и компилятор ругается, вот вам окончательный вариант всего кода контроллера

class TestPlayerController extends UTPlayerController;

var vector PlayerViewOffset;

simulated function PostBeginPlay()
{
    super.PostBeginPlay();
    bNoCrosshair = true;
}

simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)
{
    if(Pawn != none)
    {
        if(Pawn.Weapon != none)
            Pawn.Weapon.SetHidden(true);

        Pawn.Mesh.SetOwnerNoSee(false);

        out_Location = Pawn.Location + PlayerViewOffset;
        out_Rotation = rotator(Pawn.Location - out_Location);
    }
}

function Rotator GetAdjustedAimFor( Weapon W, vector StartFireLoc)
{
     return Pawn.Rotation;
}

defaultproperties
{
    PlayerViewOffset=(X=-64,Y=0,Z=1024)
}
Я знаю, что подобный тип управления ужасен, но пока придется довольствоваться ним, тем более, мы его немного упростим. После завершения полной статьи, я, возможно, проведу несколько экспериментов с управлением с помощью мыши.

Добавив немного кода в два скрипта мы серьезно поменяли нашу игру. Поэкспериментировав с перегрузкой функций, в частности, GetPlayerViewPoint, мы можем сделать стратегию, платформер или экшен от третьего лица.

В уроке мы воспользовались исключительно стандартными функциями. Подобных полезных функций полным полно, именно поэтому при создании нового скрипта советую часто заглядывать в исходники его родительских классов, вплоть до Actor и Object.

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



Хм... Написать Crimsonland на UDK оказывается не так трудно) а главное графика... Если поэкспериментировать с камерой (дрожь, небольшие наклоны) и добавить какой-нибудь блюр... недалеко и до зомбидривера))

Не работает, начиная с камеры. Такое ощущение, что TestPlayerController не действует абсолютно. Зато всё отлично компилируется.
В логе изначально не было [0005.67] ScriptLog: TestPlayerController spawned!. Плюс какие-то ошибки. Скрин всего лога прилагается. Я вообще всё перепробовал, хотя уверен, что как обычно где-то не заметил маленький косяк.

Даже в DafaultGame.ini прописал стандартно:

DefaultGame=TestGame.TestGame
DefaultServerGame=TestGame.TestGame
PlayerControllerClassName=TestGame.TestPlayerController
Нашел, в чём была проблема.
У вас тут PlayerControllerClass=class'TestGame.TestPlayerController' чуть неправильно. Должен быть пробел между class и 'TestPlayerController'

Heroic_Pizza, не знаю, в чем у вас была проблема, но в деф пропсах никаких пробелов быть не должно. Единственное, что тут может быть не так - необязательно писать папку со скриптами перед названием скрипта контроллера. В моем проекте спокойно работает

PlayerControllerClass=class'GFPlayerController'

lentinant, у меня без пробела не работало.

Кстати, другой вопрос появился, раз вы заглянули.
Как от третьего лица сделать камеру, используя данный туториал? Если использовать только GetPlayerViewPoint, то что там нужно изменить?

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

lentinant, в общем не всё так просто, да? Ладно, я просто не знаю, где найти туториал камеры от третьего лица с объяснениями и чтоб всё было понятно, а не просто код и куда его пихать. У вас вон объяснения почти к каждой строчке, всё ясно, хоть и сложно.

Спасибо, что уделили внимание.

Heroic_Pizza, могу дать название оригинала, это англоязычная книга. Конечно, перевожу я достаточно вольно, при необходимости дополняя текст собственными объяснениями, но, тем не менее, куски кода и рисунки перекочевали оттуда почти без изменений (разве что нужно будет изменить все Test в коде на Awesome). Она должна дать базовые знания и навыки в программировании на US. Нужно помнить, что самый важный навык программиста-амматора - умение находить необходимые элементы для своего кода в уже существующих исходниках. А туторов полно. В UDK есть полноценный сайт с инфой, где можно найти все - от редактора физики и инструкций по созданию контента до типов камер и различных жанровых элементов, правда, все также англоязычный.

lentinant, к сожалению я не так хорошо знаю английский, чтоб во-всём этом разбираться. Честно говоря для меня и русские уроки доставляют немало трудностей в их понимании. Программирование и скриптинг для меня в новинку, но я твердо решил в этом разобраться, поэтому стараюсь, как могу.
Если честно, не понимаю таких людей, как вы и подобные, как Ogasoda, которые бескорыстно и терпеливо отвечают на вопросы, пишут подробные уроки и снимают видеотуториалы. Но огромное спасибо вам - без вас такие нубы, как я оставались бы в неведении и бросали всё на начальном этапе. )

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