47 заметок с тегом

unity

Ctrl + ↑ Позднее

Баг в userInfo NotificationItem [iOS]

Если вы работаете с пуш уведомлениями в iOS и делаете это стандартными средствами Unity, то при обработке уведомления у вас могут возникнуть сложности с цифровыми значениями. Видимо Unity сам преобразует их в Int64. В тоже время, с текстовыми полями все в порядке.
Чтобы получить «нормальное» цифровое значение из пуша и преобразовать в Int, можно воспользоваться таким способом:

...
int my_int_value = 0;
object data = push.userInfo["my_int_value"];
if (data is Int64)
	my_int_value = ConvertInt64ToInt32((Int64)data);
...
// Convert function
int ConvertInt64ToInt32 (Int64 val) {
	return (int)(val & 0xFFFFFFFF);
}

Но как показывает практика, лучше использовать нативный плагин :)

2017   ios   unity   с#

О Texture2D и памяти

Если погуглить на тему Unity Texture2D, memory leak, www.texture — то можно обнаружить кучу постов с вопросами о том, почему не освобождается память. И это на на самом деле так, если ничего не предпринимать.

Намучившись со всем этим, составил небольшой список мыслей/советов:

  • Создавайте, как можно меньше Texture2D, в идеале использовать пул. И обязательно делать Destroy, когда объект уже не будет использоваться, иначе память не освободится.
  • При использовании класса WWW, также нужно удалять www.texture и делать www.Dispose.
  • Сжатие «на лету» не работает, т. е. если вы например загружаете изображение из интеренетов и потом вставляете в Image, способом ниже, то на мобильном устройстве, картинка полностью развернется в память, без сжатия. И это печально.
// data is downloaded byte[]
...
Texture2D texture = null;
#if UNITY_ANDROID
	texture = new Texture2D(2, 2, TextureFormat.ETC2_RGBA8, false);
#elif UNITY_IOS
	texture = new Texture2D(2, 2, TextureFormat.PVRTC_RGBA4, false);
#endif
texture.LoadImage(data); 
Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(.5f, .5f)));
MyImage.sprite = sprite;
  • Используйте сжатие предназначенное под конкретную платформу. Для iOS — это PVRTC4, для новых моделей подойдёт ASTC, начиная с iPhone 6. Для Android — ETC. Подробнее про это можно прочитать в мануале Unity.
  • Кроме того, сжатие не будет работать в некоторых случаях, если размеры спрайтов и атласов не равны степени 2. Т. е. размеры должны быть 128x128, 2048x2048 и т. д.

SSL/TLS в Unity

А сегодня мы будем шифровать весь трафик. А зачем? А чтобы усложнить жизнь читерам.

Если у вас мультиплеер на авторитарном сервере, естественно все действия должны контролироваться на нем. Но зная, какие команды отправлять, можно легко написать бота, который автоматизирует некоторые процессы, нарушая баланс и игру «правильных» игроков. Конечно, если сильно захотеть, можно сломать все что угодно, но усложнить жизнь взломщикам и читерам тоже можно. Будем использовать SSL.

Ничего изобретать не буду, потому что «все уже придумано до нас» :)
Для теста серверной части (на node.js) и генерации ключей используем эти скрипты. Единственное, чего там нет — это как из сертификата и ключа сделать PFX файл:

openssl pkcs12 -export -in client.crt -inkey client.key -out mycert.pfx

Этот файл понадобится для клиента. Для проверки SSL соединения берем пример с сокетами с MSDN и немного переделываем его. Получаем поток и прокидываем его через SSL.

IEnumerator UseSSL () {
	NetworkStream stream = new NetworkStream (socket);
	SslStream sslStream = new SslStream (stream, false, new RemoteCertificateValidationCallback (CertificateValidationCallback), new LocalCertificateSelectionCallback (CertificateSelectionCallback));
	bool authenticationPassed = true;		
	#if UNITY_EDITOR
		X509Certificate2 cert = new X509Certificate2(certPath, certPassword);
	#elif UNITY_ANDROID || UNITY_IOS
		WWW reader = new WWW (certPath);
		while (!reader.isDone) 
			yield return null;
		X509Certificate2 cert = new X509Certificate2 (reader.bytes, certPassword);
	#endif
	X509Certificate2Collection certs = new X509Certificate2Collection();
	certs.Add (cert);
	sslStream.AuthenticateAsClient (server, certs, SslProtocols.Tls, true);
	authenticationPassed = sslStream.IsAuthenticated;
	if (authenticationPassed) {
              ///
	}
	yield break;
}

Вот и весь квест. Теперь трафик между игровым сервером и клиентом зашифрован.

Ccылка на Github

2017   git   unity   разработка   с#

Система плагинов для iOS и Android

Простая система плагинов для мобилок. Контроллер инициализирует все плагины и обрабатывает приходящие сообщения. Обмен данными в формате JSON.

Вообще, печаль конечно, что Unity не реализует даже самые простые варианты работы с мобильными платформами, тот же браузер или камера. Может когда-нибудь...

Ссылка на Github

2017   android   ios   plugin   unity   разработка   с#

Emoji в Unity

Обновлено 1.03.2017
TextMeshPro теперь входит в состав Unity и стал бесплатным!

Как добавить поддержку эмоджи в Unity? К сожалению, решения из коробки нет. Но есть самый лучший ассет для работы с текстом Text Mesh Pro. Да, он не дешевый, но он этого стоит. Может когда-нибудь Unity его купит, и это будет стандартным решением, как они сделали с Anima2D.

В версии TMP, которая скоро должна пойти в релиз, разработчик добавил поддержку Emoji. Точнее, можно делать свои атласы, юникод эмоджи будет автоматически заменяться на картинку. Чтобы были доступны все эмоджи, нужен большой атлас. Я использовал EmojiOne. Также понадобится одна отличная программа — TexturePacker и расширение для Unity TexturePacker Importer.

  1. Загружаем все эмоджи в программу и экспортируем в формат Unity — Texture2D sprite sheet.
  2. После этого меняем Data format на JSON (Array) и делаем экспорт еще раз.
  3. Теперь полученные три файла: Emoji.png, Emoji.json и Emoji.tpsheet загружаем в Unity.

Осталось с помощью TMP Sprite Importer сгенерировать атлас для Text Mesh Pro. В результате, на iOS и Android можно использовать эмоджи.

2017   android   ios   unity   интерфейс

Добавление Google Play Services в Unity проект

Прошло время ручного копирования JAR файлов и ресурсов в папку с проектом. Все плагины для Android теперь надо компилить в AAR модули. Кроме того, если в плагине реализуются какие-то функции для работы с Google сервисами, например, пуш-уведомления, сохранение в облако, или авторизация, то нужно подключать к модулю зависимости.

Раньше (до 5 версии Unity, по-моему), в папку с проектом добавляли JAR файл со всеми Google сервисами, размером 5-6 мб, что конечно «не очень» оптимально. Теперь все сервисы разделены на отдельные AAR модули, которые хранятся в папке с SDK.

Google сделал специальное расширение для Unity, которое само подгружает нужные модули и зависимости в проект. Достаточно указать, что вы собираетесь использовать. Это очень удобно.

Google.VersionHandler.InvokeInstanceMethod(
      svcSupport, "DependOn",
      new object[] {
      "com.google.android.gms",
      "play-services-games",
      "10.0.1" },
      namedArgs: new Dictionary<string, object>() {
          {"packageIds", new string[] { "extra-google-m2repository" } }
      });

https://github.com/googlesamples/unity-jar-resolver

2017   android   git   unity   расширение   ссылки

Cериализация в XML и обратно

Обновлено 17.04.17
Продвинутая версия сериализации в XML, работает в несколько раз быстрее штатной

Как преобразовать объект в строку, например для сохранения или передачи, а потом обратно? Есть две простые функции, которые я использовал в одном из Unity проектов:

public static object Deserialize<T> (string toDeserialize) {
	XmlSerializer xmlSerializer = new XmlSerializer (typeof (T));
	StringReader textReader = new StringReader (toDeserialize);
	return xmlSerializer.Deserialize (textReader);
}

public static string Serialize<T> (T toSerialize) {
	XmlSerializer xmlSerializer = new XmlSerializer (typeof (T));
	StringWriter textWriter = new StringWriter ();
	xmlSerializer.Serialize (textWriter, toSerialize);
	return textWriter.ToString ();
}

Использовать очень просто:

Vectror3 vector = new Vector3 (10f, 10f, 10f); // какой-то объект
string data = Serialize<Vector3> (vector); // преобразовываем в строку
vector = (Vector3) Deserialize<Vector3> (data); // обратно из строки в объект
2017   unity   разработка   с#

Как убрать InputBox в Android над клавиатурой

Обновлено 11.04.2017
Есть неплохая реализация, правда заброшенная, но рабочая. Можно допилить до годноты.

Если вы не знаете, о чем речь, то эта заметка не для вас :)

Другие же, наверняка гуглили «unity hide mobile input». И не находили стандартного решения — потому что его нет. Все написано в документации:

Note: Android: only TouchScreenKeyboard.visible input field is supported, hence this value is always false.

Конечно, пользовательский ввод в играх нужно сводить к нулю, но бывают исключения. Ради такого исключения, чтобы избавиться от панели над клавиатурой, я сделал этот плагин.

Идея в том, что на экран добавляется нативное невидимое поле ввода откуда потом забирается текст. Все просто. Да, это не изящное решение, а грязный хак, но он работает — верхнего поля ввода нет и появляется стандартная клавиатура Android или iOS. Если к этому добавить ассет Text Mesh Pro, то будут еще и эмоджи. Да, еще не видно курсора. Я думаю над этим... :)

Если есть более красивое решение — киньте ссылку :)

Ссылка на Github

Unity UI data binding

Как отделить логику от интерфейса в Unity, чтобы не получилась каша?

Есть давно устоявшиеся паттерны и «best practices». Хотя для Unity последних не так уж и много, как например для node.js. Можно использовать эвенты, делегаты, обсерверы, вот это все, если говорить об использовании C# в Unity. Есть и готовые ассеты в Asset Store.

В общем, это то, что я начал писать сам, но вовремя нашел почти готовое решение, которое меня устраивает. После небольшого допиливания будет вообще супер — библиотека для простого биндинга в Unity.

Работает все очень просто:

  1. Импортируете DataBind.unitypackage в Unity
  2. Добавляете скрипт DataBindContext к родительскому объекту
  3. Добавляете скрипт Bind[нужный тип] к основным объектам
  4. Вызываете dataBindContext[key] = value для биндинга
  5. Все. Присвоили значение переменной — оно поменялось в UI Text, например.

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

Ссылка на Github

Обновление 25.01.2017
У Leopotam «прокачанная» версия биндинга https://github.com/Leopotam/LeopotamGroupLibraryUnity/tree/master/SystemUi/DataBinding

Ctrl + ↓ Ранее