首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Unity2D中以编程方式切换平铺板

如何在Unity2D中以编程方式切换平铺板
EN

Stack Overflow用户
提问于 2020-12-09 04:03:46
回答 1查看 1.2K关注 0票数 2

场景:每个季节(夏季、秋季等)用户都有不同的瓷砖调色板。如果分片中的瓷砖数量大于5或10,那么使用流行的统一技术在两者之间切换将是一件乏味的事。用户如何编程地在他们的瓷砖调色板之间切换,而不是使用像预制板这样的浪费解决方案呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-09 04:03:46

这个问题看起来很重要,团结文档会解决这个问题。然而,我发现自己挖掘多年的论坛帖子,想出我的解决方案。这是我想出来的,也不算太复杂。

  1. 创建分蘖集。将您的项目集导入为多个sprite spritesheets,并使用Unity编辑器对其进行拆分。不要费心地命名每一个精灵。每个分册都应该以同样的方式组织(灌木丛/树木/物体应该在每个季节的花式纸上的同一位置)。完成后,在“资产”文件夹中创建一个文件夹"Resources“。在资源中,创建一个文件夹"Spritesheets",并将您的样式表放在其中.

  1. 运行重命名脚本:

代码语言:javascript
复制
using UnityEngine;
using UnityEditor;
using System.Collections;

public class SpriteRenamer : MonoBehaviour
{
    public Texture2D[] texture2Ds;
    public string newName;

    private string path;
    private TextureImporter textureImporter;

    void Start ()
    {
        foreach(Texture2D texture2D in texture2Ds){
            path = AssetDatabase.GetAssetPath (texture2D);
            textureImporter = AssetImporter.GetAtPath (path) as TextureImporter;
            SpriteMetaData[] sliceMetaData = textureImporter.spritesheet;

            int index = 0;
            foreach (SpriteMetaData individualSliceData in sliceMetaData)
            {
                sliceMetaData[index].name = string.Format (newName + "_{0}", index);
                print (sliceMetaData[index].name);

                index++;
            }

            textureImporter.spritesheet = sliceMetaData;
            EditorUtility.SetDirty (textureImporter);
            textureImporter.SaveAndReimport ();

            AssetDatabase.ImportAsset (path, ImportAssetOptions.ForceUpdate);
        }
    }
}

将其附加到空场景中的空GameObject (只是为了简单起见)。将您的spritesheets拖放到Texture2D数组中。将newName字段设置为任何您想要的,它将是每个spritesheet中每个sprite名称的前缀。最后,运行场景,每个spritesheet的精灵将被重命名,以使每个对应的sprite具有相同的名称。

  1. ,我们现在已经修改了每个季节的分水岭,所以每个瓷砖都有相同的名称。下一步是创建一个带有子TilePalette的网格对象。绘制所有场景、冲突等。只要它们是网格对象的子级,就可以使用任意数量的TilePalettes。现在,创建一个名为ReskinnableTileBase:

的脚本

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;

public class ReskinnableTileBase : TileBase
{
    public Sprite sprite;

    public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
    {
        tileData.sprite = sprite;
    }
}

  1. 将此Reskinner脚本附加到网格对象:

代码语言:javascript
复制
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.Tilemaps;

public class Reskinner : MonoBehaviour
{

    Sprite[] subSprites;
    Tilemap[] tilemaps;

    void Start(){
        tilemaps = GetComponentsInChildren<Tilemap>();
        SetSkin("#INSERT DEFAULT TILE PALETTE NAME HERE#");
    }

    public void SetSkin(string name){
        reloadSprites(name);
        foreach(Tilemap tilemap in tilemaps){
            for(int x = (int)tilemap.localBounds.min.x; x < tilemap.localBounds.max.x; x++){
                for(int y = (int)tilemap.localBounds.min.y; y < tilemap.localBounds.max.y; y++){
                    TileBase tb = tilemap.GetTile(new Vector3Int(x, y, 0));
                    Debug.Log(tb);

                    ReskinnableTileBase rtb = (ReskinnableTileBase)ScriptableObject.CreateInstance(typeof(ReskinnableTileBase));

                    if(tb == null || rtb == null || tb.name.Length < 1){
                        continue;
                    }

                    Sprite replace = getSubSpriteByName(tb.name);
                    rtb.sprite = replace;
                    rtb.name = tb.name;

                    tilemap.SwapTile(tb, (TileBase)rtb);
                }
            }
        }
    }

    void reloadSprites(string name){
        subSprites = Resources.LoadAll<Sprite>("Spritesheets/" + name);
    }

    Sprite getSubSpriteByName(string name){
        foreach(Sprite s in subSprites){
            if(s.name == name){
                return s;
            }
        }
        return null;
    }
}

  1. ,给你!现在,每当您需要更改皮肤/季节/tilesheet时,只需使用对网格的Reskinner脚本的引用,并调用SetSkin方法,如下所示:

代码语言:javascript
复制
Reskinner reskinner = gridObject.GetComponent<Reskinner>();
reskinner.SetSkin("summer");
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65210466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档