Unity 2017.2 2D-тайловая карта и тайлы

Я пытаюсь использовать новую карту плиток Unity, представленную в Unity 2017.2, но я немного борюсь и задаюсь вопросом, стоит ли возиться с ней. Документация немного тонкая, и примеры отсутствуют. Я делаю старую школьную RPG сверху вниз и хотел бы использовать новые функции Tilemap, но столкнулся с парой проблем:

Во-первых, насколько я могу судить, нет видимости gameObject отдельного тайла. Согласно документации, у каждой плитки есть свой «игровой объект» (опечатка? Должен быть gameObject?). Я все еще немного сбит с толку, если это просто родительский объект gameObject или «Instanced Game Object» плитки. «Экземплярный игровой объект» для данной плитки действительно отображается в инспекторе, если вы нажимаете на плитку в сцене, но, похоже, нет способа настроить его преобразование (либо в коде, либо в инспекторе), поэтому он очень негибкий . Каков общий вариант использования экземпляра игрового объекта тайла?

В своей игре я делаю симулятор сельского хозяйства, в котором некоторые плитки можно будет обрабатывать, поэтому я подумал, что эта новая функция тайловой карты станет прекрасной возможностью опробовать новую плитку со сценариями, но я не мог понять, как ее правильно использовать с текущим документация. Я хочу, чтобы плитки меняли спрайты на основе других плиток вокруг них, но я изо всех сил пытался заставить это работать должным образом. В документации есть аналогичный пример, и я считаю, что смог бы заставить его работать, если бы потратил немного больше времени, но даже если бы я получил эту работу, похоже, у меня были бы другие блокировщики - у каждой плитки нет зацепок в обычном жизненном цикле Unity gameObject - Start () OnEnable () OnDisable () и т. Д. Так что у меня не было бы возможности создать скрипт для плитки так, как мне нужно. Я не уверен, есть ли способ обойти это, кроме создания нового общедоступного игрового объекта на плитке и простого написания сценария для этого игрового объекта, чтобы делать то, что мне нужно. Если мне нужно это сделать, функция тайловой карты в основном ничего не делает для меня, и я мог бы просто добавить эти тайлы в качестве игровых объектов на сцену. Кроме того, было бы хуже, потому что я даже не могу легко увидеть отдельные плитки в инспекторе сцены. И я также не верю, что смогу скорректировать их трансформации.

Кто-нибудь еще сталкивался с этими проблемами, и есть ли руководство, которое я могу прочитать, чтобы начать использовать новые функции Tilemap?


person Barodapride    schedule 19.10.2017    source источник
comment
Кстати, вы можете попросить перенести это на [GameDevelopment]   -  person Stephan    schedule 16.04.2018


Ответы (2)


Я согласен, что примеров пока немного, но это функция, о которой вы определенно хотите узнать.

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

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

https://github.com/Unity-Technologies/2d-extras/tree/master/Assets/Tilemap/Tiles

person Stephan    schedule 16.11.2017

У меня был тот же вопрос, и после некоторого поиска в Google и чтения я написал сценарий, который делает то, что мы хотим :)

Ваш набор плиток должен состоять из плиток 7x7 и выглядеть так (вы, вероятно, понимаете, как это работает):

Набор 49 спрайтов 0–48

Вот код:

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

#if UNITY_EDITOR
using UnityEditor;
#endif

public class BitmaskTile49 : Tile
{
    public Sprite[] sprites;
    public Sprite previewSprite;

    public Dictionary<int, int> maskIndex = new Dictionary<int, int> () {
        { 0, 0 },
        { 4, 1 },
        { 92, 2 },
        { 124, 3 },
        { 116, 4 },
        { 80, 5 },
        // { 0, 6 },
        { 16, 7 },
        { 20, 8 },
        { 87, 9 },
        { 223, 10 },
        { 241, 11 },
        { 21, 12 },
        { 64, 13 },
        { 29, 14 },
        { 117, 15 },
        { 85, 16 },
        { 71, 17 },
        { 221, 18 },
        { 125, 19 },
        { 112, 20 },
        { 31, 21 },
        { 253, 22 },
        { 113, 23 },
        { 28, 24 },
        { 127, 25 },
        { 247, 26 },
        { 209, 27 },
        { 23, 28 },
        { 199, 29 },
        { 213, 30 },
        { 95, 31 },
        { 255, 32 },
        { 245, 33 },
        { 81, 34 },
        { 5, 35 },
        { 84, 36 },
        { 93, 37 },
        { 119, 38 },
        { 215, 39 },
        { 193, 40 },
        { 17, 41 },
        // { 0, 42 },
        { 1, 43 },
        { 7, 44 },
        { 197, 45 },
        { 69, 46 },
        { 68, 47 },
        { 65, 48 }
    };

    public override void RefreshTile (Vector3Int location, ITilemap tilemap)
    {
        for (int y = -1; y <= 1; y++) {
            for (int x = -1; x <= 1; x++) {
                Vector3Int nextLocation = new Vector3Int (location.x + x, location.y + y, location.z);

                if (HasBitmaskTile (nextLocation, tilemap)) {
                    tilemap.RefreshTile (nextLocation);
                }
            }
        }
    }

    public override void GetTileData (Vector3Int location, ITilemap tilemap, ref TileData tileData)
    {
        int north   = HasBitmaskTile (location + Vector3Int.up, tilemap) == true ? 1 : 0;
        int west    = HasBitmaskTile (location + Vector3Int.left, tilemap) == true ? 1 : 0;
        int east    = HasBitmaskTile (location + Vector3Int.right, tilemap) == true ? 1 : 0;
        int south   = HasBitmaskTile (location + Vector3Int.down, tilemap) == true ? 1 : 0;
        int northwest   = HasBitmaskTile (location + Vector3Int.up + Vector3Int.left, tilemap) == true ? 1 & north & west : 0;
        int northeast   = HasBitmaskTile (location + Vector3Int.up + Vector3Int.right, tilemap) == true ? 1 & north & east : 0;
        int southwest   = HasBitmaskTile (location + Vector3Int.down + Vector3Int.left, tilemap) == true ? 1 & south & west : 0;
        int southeast   = HasBitmaskTile (location + Vector3Int.down + Vector3Int.right, tilemap) == true ? 1 & south & east : 0;

        int mask = 1 * north + 2 * northeast + 4 * east + 8 * southeast + 16 * south + 32 * southwest + 64 * west + 128 * northwest;
        mask -= mask > 255 ? 256 : 0;

        tileData.sprite = sprites [maskIndex [mask]];
    }

    public bool HasBitmaskTile (Vector3Int location, ITilemap tilemap)
    {
        return tilemap.GetTile (location) == this;
    }

    #if UNITY_EDITOR

    [MenuItem ("Assets/Create/Bitmasking/Bitmask Tile 49")]
    public static void CreateRoadTile ()
    {
        string path = EditorUtility.SaveFilePanelInProject ("Save Tile Bitmask 49", "New Tile Bitmask 49", "Asset", "Save Tile Bitmask 49", "Assets");
        if (path == "")
            return;
        AssetDatabase.CreateAsset (ScriptableObject.CreateInstance<BitmaskTile49> (), path);
    }

    #endif
}

И вот результат:  Пример того, как это выглядит

Для получения дополнительной информации вы можете проверить место, откуда я получил эту концепцию: http://www.cr31.co.uk/stagecast/wang/blob.html

person andreyrk    schedule 22.11.2017