Pull to refresh

Comments 10

А если сделать то же самое руками, собирая в StringBuilder, то кода получится в 3-4 раза меньше + будет работать быстрее (в том числе можно через InitializeOnLoad сделать автогенерацию) + будет статичный класс. Оверинженеринг в геймдеве не нужен.
Скорость не имеет значения, поскольку после изменения кода Юнити обязательно подвешивается, как минимум, на секунду, каким бы не было незначительным изменение. По сравнению с этим, разница между StringBuilder, T4 или Codedom незначительна. В конечном итоге, InitializeOnLoad можно прилепить ко всем трем подходам с равным успехом.

С остальным не могу поспорить, ваш прагматичный подход не хуже.
Вообще, имена слоев в чистом виде бесполезны, практически всегда нужны или их числовые представления или маски. Будет гораздо полезнее, если на выход будет подаваться вот такая простыня (для пустого проекта):
using UnityEngine;
namespace Client.Common {
    public static partial class UnityIdents {
        public static readonly int LayerDefault = LayerMask.NameToLayer ("Default");
        public static readonly int LayerTransparentFX = LayerMask.NameToLayer ("TransparentFX");
        public static readonly int LayerIgnoreRaycast = LayerMask.NameToLayer ("Ignore Raycast");
        public static readonly int LayerWater = LayerMask.NameToLayer ("Water");
        public static readonly int LayerUI = LayerMask.NameToLayer ("UI");
        public static readonly int LayerMaskDefault = 1 << LayerDefault;
        public static readonly int LayerMaskTransparentFX = 1 << LayerTransparentFX;
        public static readonly int LayerMaskIgnoreRaycast = 1 << LayerIgnoreRaycast;
        public static readonly int LayerMaskWater = 1 << LayerWater;
        public static readonly int LayerMaskUI = 1 << LayerUI;
        public const string TagUntagged = "Untagged";
        public const string TagRespawn = "Respawn";
        public const string TagFinish = "Finish";
        public const string TagEditorOnly = "EditorOnly";
        public const string TagMainCamera = "MainCamera";
        public const string TagPlayer = "Player";
        public const string TagGameController = "GameController";
    }
}

«partial» — чтобы можно было расширять дальше.
Решение «в лоб».

В гуе можно выставить путь до файла (имя класса возьмется из имени файла), неймспейс. Настройки сохраняются в проекте / репозитории и могут быть использованы всеми членами команды для перегенерации:
Что значит статичных классов нет? Есть. MemberAttribute.Static добавить надо к CodeTypeDeclaration, да и всё
Добавил. Полностью игнорируется, к сожалению: на выходе просто «public class Layers».
Хм, открыл ILSpy — и правда игнорируется. Однако толку от него? Статический конструктор, например, всё равно работает.
Вообще на T4 генерировать код проще (всё таки обычный шаблонизатор). Плюс он поддерживается студией/MonoDevelop и есть плагин для Юнити для автогенерации по зависимостям.
Когда пробовал использовать T4 в Unity, там требовались какие-то лишние телодвижения и утилиты, чтобы это работало. Подробности уже не помню. В любом случае, сейчас, скорее всего, таких проблем нет, потому что, наверное, проблема возникала от того, что Unity дропала шаблоны из солюшена, а теперь есть соответствующая настройка.

Забавная вещь с CodeGen в том, что он выглядит сложным со стороны, а если с ним подружиться, то все очень легко и непринужденно, как для мозга (думать), так и для пальцев (кодить).

В конечном итоге, я считаю, что все три варианта из данной статьи и комментариев — T4, CodeGen и StringBuilder — одинаково хороши. Выбор только за индивидуальными вкусовыми предпочтениями.
Забавно, но не очень полезно — все только для того, чтобы сгенерировать класс с константами, которые по своему определению меняться часто не должны, собственно как и слои в Unity вы не меняете как перчатки.

Полезней новичку знать общий паттерн — «не обращаться к слоям по литеральным строковым названиям, а через константные или readonly поля, чтобы потом менять только эти поля, а не все вхождения строкового литерала»
Взрослому проекту вредно (да и нет нужды) часто переименовывать/добавлять/удалять слои, а прототипу или молодому проекту не стоит ограничивать себя в этом: идеальное название приходит не сразу, идеальная категоризация получается не с первого раза, архитектура скачет почти так же лихо, как требования заказчика.
Sign up to leave a comment.

Articles