Unity 2017.2 2D Tilemap&瓦片

时间:2017-10-19 05:13:10

标签: unity3d unity2d

我试图使用Unity 2017.2中引入的新Unity Tilemap,但我有点挣扎,想知道它是否值得打扰。文档有点薄,缺乏示例。我正在制作一个自上而下的旧学校RPG并且很想使用新的Tilemap功能,但我遇到了几个问题:

首先,据我所知,没有人可以看到单个游戏的游戏对象'。根据文档,每个磁贴都有它自己的游戏对象' (错字?应该是gameObject?)。如果这只是父游戏对象或磁贴的实例游戏对象,我仍然有点困惑。 '实例游戏对象'如果您点击场景中的图块但是看起来没有一种方法可以调整其变换(在代码或检查器中),因此对于给定的图块确实会显示在检查器中,因此它非常不灵活。 tile实例游戏对象的常见用例是什么?

在我的游戏中,我正在制作一个农场模拟游戏,其中一些瓷砖将是“可耕种的”。所以我认为这个新的tilemap功能将是尝试新的脚本化磁贴的绝佳机会,但我无法弄清楚如何正确使用它与当前文档。我希望瓷砖根据周围的其他瓷砖更改精灵,但我努力让它正常工作。在文档中有一个类似的例子,我相信如果我花了更多的时间,我可以让它工作,但即使我确实得到它的工作,似乎我会有其他阻止 - 每个瓷砖缺乏正常的Unity gameObject生命周期的钩子 - Start()OnEnable()OnDisable()等...所以我无法按照我的需要编写磁贴脚本。我不确定除了在磁贴上创建一个新的公共游戏对象以及简单地编写该游戏对象以执行我需要的操作之外,是否还有其他办法。如果我必须这样做,tilemap功能基本上对我没有任何作用,我也可以将这些图块作为游戏对象自己添加到场景中。而且,它会变得更糟,因为我甚至无法在场景检查器中轻松看到单个瓷砖。而且我也不相信我能够调整他们的变形。

是否有其他人遇到过这些问题,是否有指南我可以阅读如何开始使用新的Tilemap功能?

2 个答案:

答案 0 :(得分:1)

我同意现在的例子很简单,但这是你绝对想要了解的一个功能。

首先,将tilemap渲染为单个网格,每个四边形纹理化为您编程的任何内容。这非常有效,并且允许使用比您更大的地图来实现每个拼贴的单个游戏对象。

在git上查看关于tile map的技术演示。有道路瓷砖,动画瓷砖,管道瓷砖等的例子。他们应该能够帮助您入门。当我下班时,我会写出道路拼贴的例子,因为那是最直接适合你打算如何使用它们的例子。

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

答案 1 :(得分:0)

我有同样的问题,经过一些谷歌搜索和阅读后,我写了一个脚本,做了我们想要的事情:))

你的瓷砖组必须有7x7瓷砖,看起来像那样(你可能理解它的工作原理):

Tileset 49 sprites 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
}

这就是结果: Example of how it looks

有关更多信息,您可以查看我从以下位置获得概念的地方: http://www.cr31.co.uk/stagecast/wang/blob.html