この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
概要
Unityを使う際、ちゃんとしたTextureがある場合Resource.Load()
で簡単にロードできますが、ネット上のものを使ったりするとき、DemoにTextureをすぐ使いたいときは、コード上でクロップしなければならないこともよくあると思います。
このブログで2D Textureをクロップする方法をメモしたいと思ういます。
やり方
今回の例は、この麻雀牌の画像を元のものとし、麻雀牌を一つずつ切り出したいです。
画像のGithub Link
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
public class TextureManager : MonoBehaviour
{
public Texture2D mahjongTileImage; // 元の画像
public List<Texture2D> textureList; // クロップした結果
// ソフト上に確認した各サイズ
int bgWidth = 273; // 青い背景を含めた牌の幅
int bgHeight = 217; // 青い背景を含めた牌の高さ
int tileWidth = 150; // 牌の幅
int tileHeight = 200; // 牌の高さ
int leftDummy = 60; // 最初の左から要らない部分
int bottomDummy = 12; // 最初の下から要らない部分
}
まず、TextureManager : MonoBehaviour
というクラスを作って、上記のメンバーを定義します。
そして、Unity Editorに、mahjongTileImage
に元の映像を指定します。
var assetPath = AssetDatabase.GetAssetPath(mahjongTileImage);
var tImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
tImporter.textureType = TextureImporterType.Default;
tImporter.isReadable = true;
AssetDatabase.ImportAsset(assetPath);
AssetDatabase.Refresh();
元の映像は.png
で直接コードで編集することはできなそうなので、一度isReadable = true
にし、編集できる形にインポートし直します。
textureList = new List<Texture2D>();
int MaxRow = 4; // Suit x 3 rows, Honor x 1 row
int MaxColumn = 10; // 9 + special 5
// 実験なので、空の部分と赤牌無視してTextureを切り出したい
List<int> tilesToIgnore = new List<int>() { 7, 8, 9, 15, 25, 35 };
// Tempのリストのリスト、「x = 0, y = 0」は左下で、実際ロードする際は「東」からなので、 その後Textureの並び順は「一萬」からにしたい
List<List<Texture2D>> tempTexListList = new List<List<Texture2D>>();
```
行、列、無視するブロック、一時使うリストのリストを定義します。
```csharp
// Scan all the tile textures from the tiles image
for (int row = 0; row < MaxRow; row++)
{
List<Texture2D> tempTexList = new List<Texture2D>();
for (int column = 0; column < MaxColumn; column++)
{
// 無視する部分
if (tilesToIgnore.Contains(row * 10 + column)) continue;
// GetPixels(x, y, width, height)
Color[] pixels = mahjongTileImage.GetPixels(leftDummy + bgWidth * column, bottomDummy + bgHeight * row, tileWidth, tileHeight);
Texture2D newTex = new Texture2D(tileWidth, tileHeight); ;
newTex.SetPixels(pixels);
newTex.Apply();
tempTexList.Add(newTex);
}
tempTexListList.Add(tempTexList);
}
// 下からロードするので、「一萬」を最初のTextureにしたので、行の順番を逆にします
tempTexListList.Reverse();
foreach (var list in tempTexListList)
{
// メンバー変数としてのリストに保存します
textureList.AddRange(list);
}
コードをGameObjectにアタッチして、シーンに入れてから実行すると、Texture予想通りキャッシュされてます。
public Texture2D GetTexture(int tileIndex)
{
// list.ElementAt()を使うため、System.Linqをインポートしてください
return textureList.ElementAt(tileIndex);
}
実際Textureを使いたい時、Indexを指定して取れます。
以上です。