Pull to refresh

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

Reading time3 min
Views37K

О чём телега


Я бы хотел описать возможности, ну и частично особенности которые присутствуют при разработке на данном движке. С 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<Health>().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();
 }


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


За один присест вспомнить удалось не много, а описать с ходу и того меньше. Но надеюсь описал действительно интересный вещи, в основном конечно по редактору. Правильно ли сделал что начал с мелочей? Я не знаю. Понравится, напишу ещё, не понравится, всё равно напишу.
Tags:
Hubs:
Total votes 36: ↑29 and ↓7+22
Comments10

Articles