はじめに
Dribbble のようなデザイン系のWEBサイトを見ていると、配色データ(拡張子.aco)がダウンロードできることがあるのですが、これはPhotoshopがないと開くことができません。
「Photoshopが無くても.acoファイルを開きたいなぁ」と思ったので、.acoファイルをUnity上で確認できるようにするツールをサクッと作ってみました。
作ったもの
.acoファイルに含まれているカラーの一覧を表示するEditorWindowを作ってみました。
ソースコード
以下のスクリプトをプロジェクト内のEditorフォルダ以下へ入れてください。
ツールが使えるようになります。
AcoImportWindow.cs
namespace AcoImporter
{
using System.IO;
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
public class AcoImportWindow : EditorWindow
{
private Vector2 scrollPosition = Vector2.zero;
/// <summary>
/// .acoファイル
/// </summary>
[SerializeField]
private Object aco;
/// <summary>
/// .acoから取り出した色
/// </summary>
[SerializeField]
private ColorData[] colors;
[MenuItem("Tools/Aco Importer")]
static void Open()
{
var window = CreateInstance<AcoImportWindow>();
window.titleContent.text = "Aco Importer";
window.Show();
}
void OnGUI()
{
this.scrollPosition = EditorGUILayout.BeginScrollView(this.scrollPosition);
EditorGUILayout.LabelField("*.aco");
EditorGUI.BeginChangeCheck();
this.aco = EditorGUILayout.ObjectField(this.aco, typeof(UnityEngine.Object), false);
if (EditorGUI.EndChangeCheck())
{
this.colors = null;
}
EditorGUI.BeginDisabledGroup(this.aco == null);
if (GUILayout.Button("Import"))
{
this.colors = GetColors(this.aco).ToArray();
}
EditorGUI.EndDisabledGroup();
if (this.colors != null)
{
// 色の一覧を表示
foreach (var color in this.colors)
{
string rgb = color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2");
EditorGUILayout.BeginVertical("Box");
GUILayout.Space(-1f);
EditorGUILayout.LabelField(rgb, GUILayout.Width(80f));
GUILayout.Space(-3f);
EditorGUI.BeginChangeCheck();
color.Color = EditorGUILayout.ColorField(color.Color);
if (EditorGUI.EndChangeCheck())
{
color.R = (byte)(color.Color.r * 255);
color.G = (byte)(color.Color.g * 255);
color.B = (byte)(color.Color.b * 255);
}
GUILayout.Space(2f);
EditorGUILayout.EndVertical();
GUILayout.Space(2f);
}
}
EditorGUILayout.EndScrollView();
}
/// <summary>
/// .acoファイルの色を取り出す
/// </summary>
static IEnumerable<ColorData> GetColors(Object aco)
{
// .acoのバイナリを取得
byte[] b = ToBinary(aco);
// 色の個数が入っている場所は b[3]
int colorCount = b[3];
// RGB値を取り出していく
int pos = 6;
for (int i = 0; i < colorCount; i++)
{
ColorData color = new ColorData();
color.R = b[pos];
color.G = b[pos + 2];
color.B = b[pos + 4];
color.Color = new Color(color.R, color.G, color.B, 255f) / 255f;
yield return color;
pos += 10;
}
}
/// <summary>
/// Assetをバイト列にする
/// </summary>
static byte[] ToBinary(Object asset)
{
var split = AssetDatabase.GetAssetPath(asset).Split('/');
var path = Application.dataPath + "/";
for (int i = 1; i < split.Length - 1; i++)
{
path += split[i] + "/";
}
path += split[split.Length - 1];
FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader bin = new BinaryReader(fileStream);
return bin.ReadBytes((int)bin.BaseStream.Length);
}
/// <summary>
/// 色のデータ
/// </summary>
[System.SerializableAttribute]
public class ColorData
{
public byte R;
public byte G;
public byte B;
public Color Color;
}
}
}