об играх, разработке на Unity и личном опыте

Buffer icon Проекты
Позднее Ctrl + ↑

Рисование кривых в Unity

Как нарисовать линию в Unity? А как кривую Безье? Очень просто! В Unity уже есть достаточно продвинутый компонент LineRenderer, его то я и использовал в одном из своих проектов. После упаковки в один скрипт, я бы даже сказал — в одну функцию, получилось вот что:

Можно настраивать количество сегментов в линии (качество), начальный и конечный цвет, и конечно ширину.

Исходник на Github

Выполнение в главном потоке Unity

Обновлено 18.09.2017
Лучше использовать Dispatcher из UnityToolbag.

Как в Unity быстро запустить процедуру в основном потоке? Для таких вещей, у меня есть маленький скрипт Tasker.

using UnityEngine;
using System.Collections.Generic;

public delegate void Task ();

public class Tasker : MonoBehaviour {

	private static Tasker _instance;								
	private Queue<Task> _taskQueue = new Queue<Task> ();
	private object _queueLock = new object ();

	void Awake () {
		_instance = GetComponent<Tasker>();
	}
		
	void FixedUpdate () {
		lock (_queueLock) {
			if (_taskQueue.Count > 0)
				_taskQueue.Dequeue ()();
		}
	}

	public static void Run (Task newTask) {
		lock (_instance._queueLock) {
			if (_instance._taskQueue.Count < 100)
				_instance._taskQueue.Enqueue (newTask);
		}
	}
}

Чтобы запустить что-то в главном потоке, нужно вызвать функцию Run:

Tasker.Run (new Task (delegate {
// выполнение в главном потоке
}));

JSON в Unity

Отличная легкая библиотека для работы с JSON в C#. Раньше использовал SimpleJSON, как и многие наверно, но эта оказалась проще и удобнее. Рекомендую.

https://github.com/AngelQuirogaM/NiceJson

Блоги про Unity

Этот список будет постоянно обновляться
Обновлено 17 октября 2016

Список более-менее обновляющихся блогов, сайтов, каналов на Youtube посвященных Unity, не модели-звуки-спрайты-текстуры, а уроки, статьи и заметки. Если вы знаете интересный ресурс про Unity пишите на mail@mopsicus.ru или в комменты.

На английском
http://www.unitygeek.com/
https://www.raywenderlich.com/category/unity
http://blog.theknightsofunity.com
http://www.completeunitydeveloper.com/blog
https://www.reddit.com/r/Unity3D/
http://barankahyaoglu.com/dev/
http://coffeebreakcodes.com
http://unityready.com
https://www.youtube.com/playlist?list=PLb34wPRpZdVfnN8jKtL9uqs6YSiPybBTV
http://noobtuts.com/unity

На русском
http://www.gamedev.ru/tags/Unity
https://habrahabr.ru/search/?q=unity3d
http://unity3d.ru/distribution/index.php
https://www.youtube.com/playlist?list=PLFRHm3BH1UqOGx23fUfw-T8-uPLZLUPMC
https://vk.com/unity_engine
https://www.youtube.com/playlist?list=PLD1B2C1D095B583B7
http://null-code.ru

Бесконечный скроллинг в Unity

Обновлено 07.09.2018
Теперь можно использовать ячейки разной высоты!
Добавил новые демки

Когда делаешь игру под мобильную платформу, пусть Android или iOS, иногда хочется использовать стандартные для этой платформы компоненты, потому что они проверены, оптимизированы и быстро работают. Например, списки. Кто делал в Unity интерфейс с большим количеством прокручивающихся элементов в Scrollrect, наверняка замечали, что после определенного количества, вся эта конструкция начинает притормаживать. Наиболее оптимально использовать т. н. data driving подход, когда количество видимых элементов не меняется, а данные подгружаются динамически в нужную ячейку.

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

Была сделана такая знакомая мобильным разработчикам функция, как pull-to-refresh, также, ячейки можно настраивать как угодно под ваш проект, нужное количество создается автоматически в зависимости от высоты экрана. Единственное ограничение — высота ячейки не динамическая.

Использовать очень легко — все делает один скрипт, вещаем его на Scrollview настраиваем параметры и коллбеки и все. Демо есть. Если будут какие-то вопросы и пожелания, не стесняйтесь писать. Удачи!

Ссылка на Github

Применение материала к нескольким объектам

На самом деле, заголовок не полностью отображает возможности этого скрипта — изменять можно не только материал, а вообще производить над объектами какие-либо манипуляции: изменение параметров, добавление компонентов, и т. д. Нужно лишь немного изменить код.

Суть в том, что когда сцена построена, а вам необходимо применить изменения к 30 объектам (или больше), то это может занять время. Конечно, нужно обязательно все делать через префабы, чтобы такие случаи свести к минимуму, но все же, ситуации бывают разные.

using UnityEngine;
using System;
using UnityEditor;
using UnityEngine.UI;
 
public class AssignMaterial : ScriptableWizard {
    public bool isRecursively =  true;
    public Material material;
    string label = "Select Game Objects";
    GameObject[] objects;
   
    void OnWizardUpdate () {
        helpString = label;
        isValid = (material != null);
    }
   
    void OnWizardCreate () {
        objects = Selection.gameObjects;
        foreach (GameObject go in objects){
            changeMaterial(go);
        }
    }
 
    void changeMaterial (GameObject go) {
        if (go.GetComponent<YOUR_COMPONENT> ()) {
            go.GetComponent< YOUR_COMPONENT> ().material = material;
        }
        if (isRecursively) {
            for (int i = 0; i < go.transform.childCount; i++) {
                changeMaterial(go.transform.GetChild(i).gameObject);
            }
        }
    }
 
    [MenuItem ("Custom/Assign Material", false, 4)]
    static void assignMaterial () {
        ScriptableWizard.DisplayWizard ("Assign Material", typeof(AssignMaterial), "Assign");
    }
}

Создав такой скрипт и положив его в папку Editor вы создадите свой пункт в главном меню Unity. Выбираете Custom → Assign Material и появляется окно применения материала. Выбираете нужный материал, а на сцене объекты к которым его применить и жмете Assign. Готово.

В данном примере, я применял новый материал к компоненту Image.

Структура Unity проекта

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

Можно гуглить «best practices» и смотреть как делают другие, но все равно вы придёте к своему комфортному расположению ресурсов и элементов на сцене. А для тех, кто еще не определился с выбором, предлагаю свой вариант.

И так, структура папок:

  • Editor
  • Audio
    • Music
    • Effects
  • Models
  • Plugins
    • iOS
    • Android
  • Prefabs
  • Resources
    • Prefabs
    • Sprites
    • Etc
  • Textures
  • Animations
  • Scenes
    • Levels
    • Menu
    • Etc
  • Scripts
  • Shaders
  • Vendor

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

Структура сцены:

  • Plugins
  • Scripts
  • Level
  • UI
  • Render
    • Cameras
    • Lights
    • Effects
  • !Temporary

Scripts служит для скриптов которые не связаны с объектами, например, менеджер звуков. Plugins нужен если обрабатываете входящие сообщения из плагинов iOS и Android. В !Temporary добавляются динамические, временные элементы созданные в процессе игры. Если вы делаете 2D игру, то в Level разумно было бы добавить разбивку по «слоям»: background, middleground, foreground.

Пробуйте, создавайте! Все придет с опытом. В любом случае, такой шаблон удобнее и практичнее, чем куча файлов в корневой папке и раскиданные элементы по сцене :)

Поиск по Unity репозиториям

Отличный сайт, позволяет искать в Unity репозиториях Github. Разбивка по категориям, новинки, фильтры, понятное визуальное представление. Рекомендую.

http://unitylist.com

Unity share плагин для iOS и Android

Каждый разработчик пытается автоматизировать процесс. В результате, создаются собственные движки, врапперы, надстройки, «велосипеды» и т. д... Так и получилось, нужно было сделать более-менее универсальный способ шаринга в Unity проекте для андроидов и айфонов, в результате написал эти два плагина. Теперь запросы типа: «как расшарить из Unity», «unity share plugin», «как отправить вконтакте из unity» должны вести сюда :)

Использовать очень просто. Есть небольшие заморочки с настройкой проекта под iOS, но это делается один раз и автоматически, с помощью обработки проекта после билда. Можно добавлять, изменять и использовать как угодно, все исходники и пример на Github.

В данный момент можно шарить в:

  • ВКонтакте
  • Facebook
  • Twitter
  • Одноклассники
  • WhatsApp
  • Viber
  • Telegram

Интерфейс в Unity выглядит так:

// vk, fb, ok, tw, wa, vb, tg
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class Sharing : MonoBehaviour {

	#if UNITY_IOS
		[DllImport ("__Internal")]
		private static extern void shareVia (string app, string message, string url, string param);
	#endif

	// Поделиться 
	public static void ShareVia (string app, string message, string param = "") {
		#if UNITY_ANDROID
			message = string.Format ("{0} {1}", message, "http://my.url.com"); // добавление ссылки
			using (var plugin = new AndroidJavaClass("com.mycompany.sharing.Plugin")) {
				plugin.CallStatic("shareVia", app, message);
			}
		#elif UNITY_IOS
			shareVia (app, message, "http://my.url.com", param);
		#endif
	}
		
	// Не удалось расшарить
	void OnShareError (string result) {
		switch (result) {
			case "NotInstall":
				// приложение не установлено
				break;
			case "NotAvailable":
				// шаринг не доступен
				break;
			case "AccessDenied":
				// нет доступа
				break;
			default:
				// не удалось расшарить текст
				break;
		}
	}
}

Например, чтобы расшарить в Facebook, достаточно вызвать:

Sharing.ShareVia ("fb", "Hi from Unity");

Для работы некоторых API, нужны ID приложений. Чтобы их получить, необходимо создать приложения для этих соц. сетей, как это сделать обычно написано в специальном разделе для разработчиков на сайте. Например, как для ВКонтакте.

Внутренности каждого плагина тут расписывать не буду, исходники все доступны, если будут вопросы пишите — почта внизу страницы.

Исходник на Github

 2 комментария    1290   2016   android   ios   plugin   unity

Загрузка файлов с сервера в Unity

Простой пример, как загружать файлы в игру со своего сервера. Например, для уменьшения установочной файла — тяжелые текстуры и звуки загружаем при первом запуске игры или в фоне. Вешаем скрипт на объект и пользуемся.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class HTTP : MonoBehaviour {

	public delegate void HTTPResponse (int code, WWW www);		
	public const int OK = 100;														
	public const int ERROR = 101;													
	private static HTTP _http;					

	public static HTTP instance {
		get {
			if (!_http) {
				_http = FindObjectOfType (typeof (HTTP)) as HTTP;
				if (!_http) 
					Debug.LogError ("There needs to be one active HTTP script on a GameObject in your scene.");
			}
			return _http;
		}
	}

	public static void GET (string url, HTTPResponse callback) {
		instance.StartCoroutine (instance.WaitForRequest (new WWW (url), callback));
	}

	public static void POST (string url, Dictionary<string, string> postData, HTTPResponse callBack) {
		WWWForm form = new WWWForm();
		foreach (KeyValuePair<String, String> param in postData)
			form.AddField(param.Key, param.Value);
		instance.StartCoroutine (instance.WaitForRequest (new WWW (url, form), callBack));
	}

	IEnumerator WaitForRequest (WWW www, HTTPResponse callback) {
		yield return www;
		if (www.error == null)
			callback (OK, www);
		else 
			callback (ERROR, www);
	}
}

Можно запускать хоть несколько потоков. Использовать очень просто:

HTTP.GET ("http://yandex.ru", (int code, WWW www) => {
	if (code == HTTP.OK) {
		string html = Encoding.UTF8.GetString (www.bytes, 0, www.bytes.Length);
		Debug.Log (html);
	} 
});

Только не забывайте освобождать объект WWW в коллбеке :) www.Dispose();

Ранее Ctrl + ↓