четверг, 26 декабря 2013 г.

My Dissolve Shader for Unity3D

Эх, помню три года назад когда только начинал путь в программирование и разработку игр, увидел демонстрацию такого же шейдера. Он меня привёл в поросячий восторг, и я считал что чтобы сделать его, нужно быть гуру. Но оказалось всё на много проще, сидел, делать нечего, вспомнил про эту штуку, сделал за 10 минут :c

Первый вариант


      Второй вариант



понедельник, 23 декабря 2013 г.

Вещи которые вы возможно не знали о Unity3D [Хабра]

О чём телега

Я бы хотел описать возможности, ну и частично особенности которые присутствуют при разработке на данном движке. С Unity3D работаю уже около трёх лет, так что мыслей накопилось достаточно для средненькой такой статьи. Местами буду через чур мудрить, и рассказывать о том что вам вряд ли пригодится, но по большой части рассказ будет о очень простых и часто используемых вещах (если знать о них конечно).

Режим редактора для дебага.

Знаете такие моменты, когда у нас есть приватное поле у компонента, и нам нужно посмотреть его значение? Я раньше всегда либо выводил его значение в лог, или по быстрому отмечал нужными атрибутами его или вовсе делал public. Но есть способ на много круче.

image
Для демонстрации я создал простой компонент:
using UnityEngine;
using System.Collections;

public class PrivateFieldTest : MonoBehaviour {

 private int Score;

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

 image

Start, it's trap

Метод старт может работать как корутин. С Update допустим не прокатит такой ход конём.
using UnityEngine;
using System.Collections;

public class StartIsCorutineTest : MonoBehaviour {

 IEnumerator Start () 
 {
  print("I'm wait 5 second!");
  yield return new WaitForSeconds(5);
  print("I'm done!");
 }

}
Это достаточно полезно когда в старте что нибудь может вызывать не которые задержки. Конечно, можно вызывать корутин прямо из старта, но так согласитесь лаконичней.

SendMessage. Или штука которая делает вам приятно.

Я долго думал, стоит ли добавлять описание данной возможности, ибо многие и так об этом знают, но у меня оказалась пара коллег для которых данная штука оказалась открытием. Фишка то в чём. Допустим, у нас есть некий компонент и ему нужно срочно сообщить другому компоненту что-то важное. Какой обычно подход:
gameObject.GetComponent().TakeDamage(60);
Очень увлекательно, слегка массивный синтаксис (но все же мы видели C++ по новым канонам). Но главная проблема кроется в том, что мы должны знать тип компонента на который получаем ссылку. SendMessage помогает избавиться от этого нюанса, и ему нужно только знать имя метода и аргументы.
gameObject.SendMessage("TakeDamage", 60);
Проблема конечно, что не возвращает то что должен возвращать вызываемый метод. Но мы можешь создать план капкан, и получить свой маленький JS который к слову есть но это на самом деле не JS. Допустим передав в аргументах call back функцию для принятия значений для возврата. Это стильно, модно, молодёжно и не должно порицаться в современном и толерантном обществе. А ещё могут быть проблемы если весит компонент у которого есть
метод с таким же названием.

 image

Scale объекта ломает батчинг мешей

Последнее время участились вопросы на эту тему. Частично это так, сюда бы отлично зашла картинка выше. Велик шанс что он сломается, но может и не сломаться. Тут много факторов, обратимся к офф справке: - Для Dynamic Batching как правило, объекты должны иметь одинаковый Scale, исключением является то что если все объекты не равномерно масштабированы то они могут склеиться. Что это значит я сам не до конца понял, по этому просто не масштабирую. Если батчинг сломается, то это приведёт к увеличению Draw Call, что очень плохо.

 image

Выбранный объект можно закрепить в инспекторе

Полезно когда у нас очень много объектов в сцене, и нам нужно поместить ссылку на один из них в какой нибудь компонент, который уже на одном из объектов. Как правило, хватает выделения объект с компонентом, и перетаскивание объекта из иерархии. Но может появиться проблема когда оба объекта достаточно далеки друг от друга (в иерархии) из-за чего может начаться нервный тик. Но есть маленький замочек который фиксирует инспектор на определённом объекте.

image
Так же можно открыть много вкладок с инспектором и зажимать нужные на нужных объектах.

WWW Утечка памяти.

У класса WWW есть очень серьёзное проблема, которая даёт о себе знать когда нужно загрузить много текстур. В справке в пример приводится следующий код:
    IEnumerator Start() {
        WWW www = new WWW(url);
        yield return www;
        renderer.material.mainTexture = www.texture;
    }
Проблема в том, что если получать текстуру через поле то создаётся новая текстура, каждый раз, которая ещё и не хочет и из памяти выгружаться. В итоге я применил такой код, который позволяет от этого избавиться:
//код урезан в дедуктивных целях. 
public override void OnWWWFinish(WWW www)
 {
        Texture2D tex = new Texture2D(4, 4, TextureFormat.RGB24, false, false);
        www.LoadImageIntoTexture(tex);
        tex.Compress(false);
        www.Dispose();
 }

Прощальные слова

За один присест вспомнить удалось не много, а описать с ходу и того меньше. Но надеюсь описал действительно интересный вещи, в основном конечно по редактору. Правильно ли сделал что начал с мелочей? Я не знаю. Понравится, напишу ещё, не понравится, всё равно напишу.

воскресенье, 3 ноября 2013 г.

Парсинг сайтов на C#.

Для одного из своих приложений мне понадобилось достаточно много информации которой полно на различных wiki но всё это собирать вручную достаточно геморно. По этому я решил вооружится C# и распарсить всё что мне надо.  Мы будем использовать хорошую библиотеку Html Agility Pack которая берёт на себя большую часть работы и предоставляет для нас удобное DOM дерево с которым мы можем работать. Она поддерживает XPath запросы, LINQ и много всего вкусного.

воскресенье, 27 октября 2013 г.

Механизм исключений C#.

Не преодолев желания налабать что нибудь в блог, решил написать не большую статейку об исключениях в C#. Я не буду писать много воды и перейду сразу к делу. Логически я разделю статью на две части, обработка и выброс исключений. Собственно больше о них сказать мне не чего.


Не много об исключениях

Для начала определимся что такое исключения, и для чего они вообще нам нужны. На сколько мне известно, в достаточно старых языках таких как Си, для контроля за работай программы использовали примитивные способы, на подобие возврата кода ошибки из функции. Удобного в этом мало, да и попросту забыть проконтролировать код ошибки очень просто из-за чего может начаться не контролируемое поведения программы и бессонная ночь отловки бага :) Конечно в Си с помощью макросов и прочего есть не что подобное. Но в более поздних языках это представлено более лаконично. И так, смоделируем ситуацию, допустим у нас есть некий метод  который принимает пользовательский объект для последующей работы с ним. А теперь представим что мы в эту функции передали выражение со значением null. Что будет? Если метод попробует начать работу с пустышкой, система выбросит NullReferenceException, но по хорошему метод перед работай проверить правильность всех аргументов и сам выбросить нужные исключения. Выброшенная ошибка будет распространятся вверх по цепочки вызовов пока её не отловят или она не достигнет верхней точки и программа не завершится аварийно. Думаю теперь понятно зачем нужен механизм исключений?

Отлов исключений  
Для отлова исключений в C# предусмотрено три ключевых слова, все они относятся к одной системе и работает на подобии оператора if-else. Это try\catch\finaly. В тело оператора try помещается код, за которым нужно будет так сказать проследить. Catch блок обработки определённого исключения а finaly блок который будет вызван после обработки исключения для того что бы освободить ресурсы. Но по меньше лирики перейдём к коду :


....
try
{
    SomeObject _so;
    _so.SomeMethod();
}
catch(NullReferenceExcepetion e)
{
     //Обработка NullReferenceExeption
}
catch(Exception e)
{
    //Обработка вообще всех исключений
}
finaly
{
   //Блок который вызовется после обработки исключения
   // (если исчклюения не было блок не вызовется)
}
....
    
Из комментариев думаю всё ясно. Так же если вызвать некий метод в блоке try, то обработка исключения выполнится. Так же я бы хотел рассказать не много об особенности работы оператора catch. Как вы уже заметили в скобках нужно указывать класс исключения, да-да, все исключения это просто классы унаследованные от класса Exception. И все кто понимает механизм полиморфизма и ковариантности, догадаются что если объявить блок catch отлавливающий исключения Exepetion то он будет срабатывать на ВСЕ ошибки. Но, если мы хотим знать что мы именно поймали, стоит сверху от отловки Exception ловить более узкоспециализированные исключения. Так же из всех операторов catch выбирается один, тот который первый подошел. Так что не стоит указывать выше всех отлов Excepetion так как всё что ниже просто будет игнорироваться.

"Выброс" своих исключений

Для инициирования своих исключений в C# предусмотрен оператор throw. Справа от оператора указывается выражения которое имеет тип производный от System.Exception.
Проще говоря нужно указать ссылку на класс который пронаследован от System.Exception. Так же в .Net Framework пред усмотрена куча классов для этих дел, но при желание вы можете создать свои.  В общем синтаксис примерно такой:

public class ThrowTest2

 {
   static int GetNumber(int index)
   {
      int[] nums = { 300, 600, 900 };
      if(index > nums.Length)
      {
          throw new IndexOutOfRangeException();
      }
     return nums[index];
   }
   static void Main()
   {
      int result = GetNumber(3);
   }
 

Резюмируя

В заключения хочу сказать что можно найти ещё кучу всего интересного об исключениях в C#, я же взялся рассказать базовые возможности. Свои замечания пишите в комментариях, постараюсь поправить статью если что не так :)

пятница, 13 сентября 2013 г.

Впечатление от книги "C++ для профессионалов"

Достаточно давно я прочитал "Базовый курс C++" от Шилдта, книга в целом хорошая и я познал базовый синтаксис C++. Но всё не было времени практиковать да и по работе писал на C# так что частично знания C++ пропали а когда я начинал на нём писать и вовсе был некий страх что что-то делаю не так, как будто хожу по охерено тонкому льду а под ним меня ждёт разыменования нулевого указателя. Но вот один мой знакомый предложил мне написать с ним ASCII RPG, от чего я не мог отказаться. И вот я сел за написание движка и опять этот страх. Решил что так жить нельзя и нагуглил "Николас А. Солтер, Скотт Дж. Клепер - C++ для профессионалов". Сказать что книга развеила мои страхи это ни чего не сказать. Она помогла переосмыслить многие вещи в ООП и понять как работает C++ в самых "низах". В общем, всем советую! В начале идёт быстрый прогон по базовому синтаксису C++ так что если вы когда то его знали или не плохо программируете на C подобных языках, то в целом книга поможет вам начать путь к действительно толковому программированию на С++.

Проба пера в создании заставки к видео.

Давича отрубили мне интернет, и я вспомнил что мне не помешала бы заставка для видео туториалов. Ну вот открыл я Adobe After Effects ии.. всё пропало. Точнее из-за кряка всё не захотело нормально работать и я решил склепать что нибудь простенькое в Sony Vegas. В итоге получилось вот что.

Видео

среда, 11 сентября 2013 г.

RayCast Tutorial

 Записал новый туториал, который планировал очень давно но всё не как не было возможности. Но вот я купил новый микрофон, к слову микрофон достаточно не плохой, вокальный все дела, но звуковая карта из мат платы по этому этого почти не заметно :)

Видео

четверг, 15 августа 2013 г.

Набитие первой тату

Сделал такое вот творчество на своей руке, конечно в мой адрес после такого будет вполне адекватно высказывание "Позёр" от части так и есть, но программирую тоже не плохо. В начале хотел набить "00001010" что в десятичном числе давало 10, число десять мне нравится хотя бы из-за теории 10к часов, которые нужно потратить на обучения что бы добиться успеха. Но первый вариант не понравился из-за того что нулей слишком много, а для меня в татуировки главное красота как никак, в итоге сменил на "01101010" что является десятичным числом 106 которое для меня  не имеет ни какого смысла.  Всё прошло достаточно быстро и не больно, за работу отдал 1500 что дёшево, вроде как этот салон является топовым для моего не большого города.


понедельник, 29 июля 2013 г.

Регистрация на BrainStorage

Не без известный создатели хабры запустили таки один из своих проектов "BrainStorage" получился эдакий LinkedIn более таргетированый под русско язычную аудиторию.  Решил не оставаться в стороне и тоже зависти аккаунт http://brainstorage.me/HolyMonkey

пятница, 26 июля 2013 г.

Как я боролся с блокировкой переходов на мой сайт из VK

У меня имеется группа сайта в VK, всё хорошо размещаю туда ссылки на новый контент, но тут случился нежданчик, переход на статьи по OpenGL заблокировали, а так как из VK идёт 25% трафика, я не мог просто так это пропустить. Отписался в службу поддержки, там ответили что на сайте вирус (К слову яндекс раньше тоже находил но быстро одумался). Служба поддержки долго говорила что нашли вирус, но что он из себя представляет не говорили. В результате разблокировали, прилагаю скрин переписки.



вторник, 16 июля 2013 г.

TV Noice Effect Generator

Наконец-то, я пробился в ассет стор. Моим дебютным ассетом стал маленький пакет для генерации эффекта потери сигнала для телевизора.

Описания на моём сайте
[DEMO]
[Asset Store]

среда, 15 мая 2013 г.

Мой новый проект "Blood".

Решил начать не большой проект, просто ради интереса. Больших надежд на него не ставлю, но обкатывать не которые фичи на нём очень даже удобно. Планирую геймплей схожий  "Quake 3 arena". Благо подружился с физикой в Unity3D, хоть и были нюансы требующие  костылей, допустим что бы получить одну из компонентов вектора ускорения, пришлось вызывать метод ToString() у вектора и парсить строку, так как взятия компонента на прямую выдавало рандомные числа.

Vector3 _vel = rigidbody.velocity;
yVelocity = Convert.ToDouble(_vel.ToString().Split(',')[1]);

 А так, Unity3D в который раз продемонстрировала мне свою мощь. Так же промучился с позиционированием 3D объектов на экране, делал 3D GUI, к счастью с задачей справился, удалось сделать симпатичный 3D радар ;). В планах сделать нормальные ригнутые руки и пару типов оружия, да мультиплеер. С первый справится можно, но вот второе требует вложений, по типу локальной сети делать не хочу, по этому нужно будет брать сервер, да и ещё где то хранить инфу о игроке. Надеюсь что со временем сделаю приличную игру со своим донатом и фичами :). 

P.S Игра будет для соц. сетей.

Группа
Игра

Cтрим за 16.05.2013

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


среда, 24 апреля 2013 г.

Клинт серверный чат на Unity3D + C#.


Решил не много рассказать о клиент серверном чате с использованием Unity3D и C#'. Применялись классы TCPClient и TCPListener.

воскресенье, 17 марта 2013 г.

пятница, 25 января 2013 г.

Отличия структуры от класса C#.

Тем кто усиленно изучал C++,  может показаться не обычным то что, структура таки отличается от класса, меня это например удивило, и я даже один раз ошибся.
Сейчас попробую описать главные отличия.
  • Структура не может наследовать другой класс или структуру (интерфейс можно).
  • Структуру нельзя унаследовать.
  • Если объявить переменную с типом структуры, то там будет хранится структура. а не ссылка на неё, как в случае с классом. 
  • Все члены структуры по умолчанию public. 
  • Члены структуры не могут быть protected. 
  • Структура не содержит деструктора.   
 Не много расскажу о третьем пункте. Многие не поймут разница. К примеру рассмотрим такой вот пример.


struct tempStruct
{
   public int i;
}
class tempClass
{
   public int i;
}

tempClass tc = new tempClass();
tempClass tc2 = new tempClass();
tempStruct ts;
tempStruct ts2;
tc = tc2;
tc2.i = 10;
ts.i = 10;
ts2 = ts;
ts2.i = 20;


в результате 

tc.i == 10;
tc2.i == 10;
ts.i == 10;
ts2.i == 20;

При работе с классами, у нас передаются ссылки по переменным. А в случаи со структурами они полностью копируются. Так же, при работе с unsafe кодом, указатели могу ссылаться на структуру при условие что в ней нету ссылочных значений. С классами указатели работать не могут, только с их полями.



История записи нового видео урока.

С того момента как я выложил последнее видео о создании RTS, прошло уже чуть более месяца. И всё это время я вынашивал идею по записи очередного цикла, и как всегда было одно "но", не было темы. И вот я вспомнил про своего товарища Игоря, которому совсем не давно помогал разобраться с указателями в С++, а так как я фанатирую на Unity3D было решено в добавок помочь разобраться и с этим инструментом, да и в добавок заснять всё это и выложить на YouTube.
Первая попытка оказалась не много провальной, я забыл активировать лицензию программы для захвата видео с экрана, и в итоге 20-минутная запись была изуродована надписью "Не зарегистрированная копия". Но я не расстроился, и таки зарегистрировал и на следующий день решили переснять.
Вторая попытка была по лучше, но из-за того что, всё рассказывать второй раз, показалось мне скучным делом, я решил импровизировать из-за чего вся моя речь была скомкана. Сразу после записи, мы продолжили и записали ещё одно видео, продолжительностью уже в 63 минуты, и всё это время без остановки я втирал про Наследования, Полиморфизм и о некоторых специфичных для разработчиков игр вещах. Первое видео было удачно смонтировано (хоть я и забыл убрать в начале не много), но вот второе. Во втором, оказалось слишком много ляпов с моей стороны, то я сказал что между структурой и классом нету совершенно не какой разницы, то Полиморфизм назвал полиформизмом, в целом всё прошло нормально, но вот из-за этих ляпов выкладывать не буду :).


понедельник, 21 января 2013 г.

Первый конкурс на моём сайте.

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