О чем этот пример

При переносе игровых ресурсов из Unity в Phaser разработчики часто сталкиваются с необходимостью работы с текстурами, экспортированными из Unity Editor. Phaser предоставляет специальный загрузчик для чтения `.meta` файлов Unity, что позволяет автоматически нарезать спрайтшит на отдельные кадры. Эта статья покажет, как загрузить Unity-атлас и отобразить конкретные спрайты из него на сцене, сохранив все исходные настройки.

Версия Phaser: код и демо в этой статье рассчитаны на Phaser 3.90.0.

Живой запуск

Ниже встроен рабочий билд примера. Оригинальный источник: GitHub.

Исходный код


class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
        this.load.unityAtlas('asteroids', 'assets/atlas/asteroids.png', 'assets/atlas/asteroids.png.meta');
    }

    create ()
    {
        this.add.image(200, 200, 'asteroids', 'asteroids_7');
        this.add.image(400, 200, 'asteroids', 'asteroids_10');
        this.add.image(600, 200, 'asteroids', 'asteroids_13');
        this.add.image(200, 400, 'asteroids', 'asteroids_17');
        this.add.image(400, 400, 'asteroids', 'asteroids_21');
        this.add.image(600, 400, 'asteroids', 'asteroids_30');
    }
}

const config = {
    type: Phaser.WEBGL,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Подготовка базового URL и загрузка атласа

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

Загрузка Unity-атласа выполняется в методе preload(). Метод this.load.unityAtlas() принимает три ключевых аргумента: ключ для дальнейшего обращения к атласу, путь к изображению (PNG) и путь к файлу метаданных (.meta), который генерирует Unity.

preload ()
{
    this.load.setBaseURL('https://raw.githubusercontent.com/phaserjs/examples/master/public/');
    this.load.unityAtlas('asteroids', 'assets/atlas/asteroids.png', 'assets/atlas/asteroids.png.meta');
}

После вызова этого метода Phaser загрузит изображение и проанализирует .meta файл, чтобы корректно разбить спрайтшит на отдельные текстуры (фреймы). Все эти фреймы будут доступны под общим ключом 'asteroids'.

Отображение спрайтов из загруженного атласа

После успешной загрузки атласа в методе create() мы можем добавлять его отдельные фреймы на сцену как самостоятельные изображения. Для этого используется метод this.add.image().

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

create ()
{
    this.add.image(200, 200, 'asteroids', 'asteroids_7');
    this.add.image(400, 200, 'asteroids', 'asteroids_10');
    // ... другие спрайты
}

Здесь 'asteroids' — ключ атласа, а 'asteroids_7', 'asteroids_10' и т.д. — имена конкретных фреймов (спрайтов), которые были извлечены из .meta файла Unity. Phaser автоматически создаст и отрисует изображение, используя только область этого фрейма.

Конфигурация игры и запуск сцены

Чтобы все работало, необходимо создать конфигурационный объект игры и передать в него нашу сцену Example.

const config = {
    type: Phaser.WEBGL,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

В этом конфиге мы указываем тип рендерера (WEBGL), размеры холста, ID HTML-элемента, в который будет встроена игра, и класс нашей сцены. После создания экземпляра Phaser.Game автоматически запустится жизненный цикл сцены: init(), preload(), create() и далее update().

Как Phaser обрабатывает Unity .meta файлы

Файл .meta, который генерирует Unity для текстуры, содержит важные данные: размеры исходного изображения, настройки импорта и, что самое главное для нас, информацию о нарезке (slicing) — координаты и имена каждого отдельного спрайта.

Когда вы вызываете this.load.unityAtlas(), Phaser: 1. Загружает PNG-изображение как обычную текстуру. 2. Асинхронно загружает и парсит соответствующий .meta файл. 3. На основе данных из файла создает внутри текстуры набор фреймов (frames). Каждый фрейм получает имя, которое было задано в Unity (например, asteroids_7).

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

Что попробовать дальше

Использование this.load.unityAtlas() — это эффективный способ переноса графики из Unity в Phaser без потери структуры атласа. Для экспериментов попробуйте загрузить собственный .meta файл и спрайтшит, экспортированный из Unity, или используйте this.anims.create() для создания анимации из последовательности фреймов, загруженных этим методом. Также стоит изучить содержимое загруженной текстуры через this.textures.get('asteroids').frames, чтобы увидеть все доступные имена фреймов.