【问题标题】:Unity 2017.2 2D Tilemap & TilesUnity 2017.2 2D Tilemap & Tiles
【发布时间】:2017-10-19 05:13:09
【问题描述】:

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

首先,据我所知,单个图块的“游戏对象”是不可见的。根据文档,每个图块都有自己的“游戏对象”(错字?应该是游戏对象?)。如果这只是父游戏对象或图块的“实例化游戏对象”,我仍然有点困惑。如果您单击场景中的图块,给定图块的“实例化游戏对象”确实会显示在检查器中,但似乎没有办法调整其变换(在代码或检查器中)所以它非常不灵活. tile 的实例化游戏对象的常见用例是什么?

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

还有其他人遇到过这些问题吗?有没有我可以阅读的指南来了解如何开始使用新的 Tilemap 功能?

【问题讨论】:

  • 顺便说一句,您可能希望将此迁移到 [GameDevelopment]

标签: unity3d unity2d


【解决方案1】:

我同意现在的示例很少,但这是您绝对想了解的功能。

首先,tilemap 被渲染为单个网格,每个四边形都根据您的编程设置纹理。这是非常有效的,并且允许的地图比您使用每个图块的单个游戏对象所能实现的要大得多。

查看 git 上瓦片地图的技术演示。有道路瓷砖、动画瓷砖、管道瓷砖等的例子。它们应该能够让你开始。下班后,我会写出道路瓷砖示例,因为这是最直接符合您打算如何使用它们的示例。

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

【讨论】:

    【解决方案2】:

    我也有同样的问题,在谷歌搜索和阅读之后,我写了一个脚本来做我们想要的:)

    您的图块集必须有 7x7 的图块并且看起来像这样(您可能了解它的工作原理):

    代码如下:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      • 1970-01-01
      • 2018-09-18
      • 1970-01-01
      相关资源
      最近更新 更多